{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "#skip\n",
    "! [ -e /content ] && pip install -Uqq fastai  # upgrade fastai on colab"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#default_exp torch_core"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "from fastai.imports import *\n",
    "from fastai.torch_imports import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from PIL import Image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "from nbdev.showdoc import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "_all_ = ['progress_bar','master_bar']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "if torch.cuda.is_available():\n",
    "    if torch.cuda.current_device()==0:\n",
    "        def_gpu = int(os.environ.get('DEFAULT_GPU') or 0)\n",
    "        if torch.cuda.device_count()>=def_gpu: torch.cuda.set_device(def_gpu)\n",
    "    torch.backends.cudnn.benchmark = True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Torch Core\n",
    "\n",
    "> Basic pytorch functions used in the fastai library"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Arrays and show"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@delegates(plt.subplots, keep=True)\n",
    "def subplots(nrows=1, ncols=1, figsize=None, imsize=3,suptitle=None, **kwargs):\n",
    "    if figsize is None: \n",
    "        h=nrows*imsize if suptitle is None or imsize>2 else nrows*imsize+0.6 #https://github.com/matplotlib/matplotlib/issues/5355\n",
    "        figsize=(ncols*imsize, h)\n",
    "    fig,ax = plt.subplots(nrows, ncols, figsize=figsize, **kwargs)\n",
    "    if suptitle is not None: fig.suptitle(suptitle)\n",
    "    if nrows*ncols==1: ax = array([ax])\n",
    "    return fig,ax"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "_,axs = subplots()\n",
    "test_eq(axs.shape,[1])\n",
    "plt.close()\n",
    "_,axs = subplots(2,3)\n",
    "test_eq(axs.shape,[2,3])\n",
    "plt.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _fig_bounds(x):\n",
    "    r = x//32\n",
    "    return min(5, max(1,r))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@delegates(plt.Axes.imshow, keep=True, but=['shape', 'imlim'])\n",
    "def show_image(im, ax=None, figsize=None, title=None, ctx=None, **kwargs):\n",
    "    \"Show a PIL or PyTorch image on `ax`.\"\n",
    "    # Handle pytorch axis order\n",
    "    if hasattrs(im, ('data','cpu','permute')):\n",
    "        im = im.data.cpu()\n",
    "        if im.shape[0]<5: im=im.permute(1,2,0)\n",
    "    elif not isinstance(im,np.ndarray): im=array(im)\n",
    "    # Handle 1-channel images\n",
    "    if im.shape[-1]==1: im=im[...,0]\n",
    "\n",
    "    ax = ifnone(ax,ctx)\n",
    "    if figsize is None: figsize = (_fig_bounds(im.shape[0]), _fig_bounds(im.shape[1]))\n",
    "    if ax is None: _,ax = plt.subplots(figsize=figsize)\n",
    "    ax.imshow(im, **kwargs)\n",
    "    if title is not None: ax.set_title(title)\n",
    "    ax.axis('off')\n",
    "    return ax"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`show_image` can show PIL images..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAYAAAA4E5OyAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAH0klEQVR4nO2bS08TbRvHf51Dh9LSg7S2gYBQSFGhhKAJaowkLNi6MFE+gF/GL6A7E1euXLlxhzERJFRoJFEolnIoyKEFWqGlM23nXWj72oKHR5ni86S/ZBbMXEyv/vvvfV/3NXdNuq5T5/8IZ53A30ZdkCrqglRRF6SKuiBVSD+5/l+egkwnnaw7pIq6IFXUBamiLkgVdUGqqAtSxc+m3T+mUCigaRqappHJZNA0jVwuV77e1NSE1WrFZPoyC8qyjCzLRqf1XQwXJJvNsry8zPz8POPj4ywtLREKhSitssfGxhgbG0MURQRBoKurC7fbbXRa38UwQUpO2NraYmZmhsXFRaLRKEtLSySTybIg0WiUqakpRFFEkqSyQxRFwWw2YzKZyu6pBaaf9EN+q1LVdZ1UKsXc3ByvXr3i0aNHZDIZDg8PKRaLFAqFcmxJAEEQEASBu3fvMjo6ypUrV2hpaUGSJERR/J00fsaJKp+6Q3Rdp1AokMlkWFhYYH19nVQqhaqq5PP5L5l884nn8/mK87FYjOnpafL5PN3d3bS1teFwOJBl2Shhjr+BHxz/mHw+r2cyGT0UCul37tzRBwYGdFEUdUEQfumQZVlvaGjQm5ub9fb2dv3hw4f60tKSfnh4+Dvp/IgT3/OpO8RkMiEIAlarFZ/PRzqdxmQylceM0pggyzKSJFEsFikWi+TzeQqFQvkAUFWVzc1Ntre3cblcNDY2nna6xzj1OkQQBBRFwePxMDIyQjAYLI8R3153OBy0trZy/vx5XC4XDQ0NFfdRVZVMJsPi4iITExOk0+nTTvVEDJtlFEUhEAhwcHDAzZs3OTo6IpfLlY9gMEhfXx+7u7skk0nC4TDv37+vuIeu66TTaba2tshkMuTzeURRNHTWMUwQm81Gb28vHo8HRVHIZrOk02l2dnZYW1vj3r17jI6OsrOzw9LSEk+ePDkmCMDKygqKopBIJGhra0NRFCTJuPLJ0MLMZDJhtVoJBoOoqoqqqqRSKdbW1ujo6EAUxYrjJPb29ojFYuzv76NpmuFVrOGVqs1m49KlS+W/VVUll8thNpt/6f8/ffrE9vY28XicTCZzbKw5bQwXBCrrDkmSvkxvv2h7p9OJw+GgubkZRVEMr1prIsi3/OjrcRJtbW0EAgFaW1uxWCyGF2d//fL/3LlzeL1ebDYbkiSVp2+jqLlD/iler5cLFy7gcDh+edz5E87cIfv7+7x9+5ZPnz6ddSrAXyDI9vY2r1+/JhKJnHUqwBl8ZXK5HEdHR8TjcWZmZgiFQszNzZFMJivivF4vXq+X69evMzw8jMvlqkl+NRektGB79uwZDx48QNO0iv5Iifb2dvr6+rh16xbBYLBmTaKaf2X29/d58+YNsVgMTdMoFosnxgUCAW7cuEFzc3NNu2Y1d8je3h4TExNEIpETnVGio6ODoaEhHA5HTVuINXdIc3Mzw8PDBAKBH8ZNTk7y+PFjPnz4QDqdRlXVmuRXc4fY7XYGBwdZWFj4Ydzk5CThcBi/34/P58Pj8dSkDqm5ILIs43a7GR0dRRAEwuEw4+Pj5HK5Cheoqoqu60QiEcLhMENDQ1gslv/eWkaSJGw2Gz09PbjdbkRRZHp6GqBCkFIrcXV1ldnZWS5fvozH40EQhH9ng+h7lDpeNpsNRVG4ffs2LS0tRCIRYrEY4XCYjx8/luNnZ2fZ3NzE6/Vy48YN/H4/TU1NhuVXM0H0b57/lPqqiqLg9/txu934/X6mpqZIpVJEo9Fy/NraGvF4nN7eXsxmc3mhZ5RLDBek9AQvHo/z8uXLCmEABgYGCAQCBAIBOjs78fl8tLS0MDU1xfz8PPBFzImJCTY2NnA4HAwMDNDS0mJIF95wQYrFItlslkgkwtOnT48JIooiPT09OJ1OGhoauHLlCgcHB2xsbJQFAYjFYsTjca5evYrL5cLtdv87BdF1HU3TSCQSLCwsHBPk+fPnrK+v093dTXd3N3Nzc0SjURKJREWcLMvYbDY8Hg/nz583rLdaE0FKLkkkEscEmZ6eZn19ncHBQRKJBOvr6+zs7PD58+fKRCUJs9mM3W7HZrMZ1ig68wZRqQrd29tjZmaGw8NDjo6O2Nvbq4izWCy4XK7yOGNUkWa4IKWFmclkQhRFCoVChUtKD65SqRSrq6vfvY8syzQ2NmK327FYLIbla/haRhRFmpqa6Orq4tq1a7S1tRn9kn9ETRwiyzJOpxO/34+u6yQSCQqFAvl8nmKxeGxcqUYQBMxmM42NjYY3mQ3ZMFNxg6+DaiaTYWdnh2QyyfLyMu/evWNqaopoNMrKysp3RXE6ndjtdu7fv8/w8DB9fX04nc4/TQtqtWHm2Kt+HTusVisWi6U8bSqKwu7uLpqmsbW1haZp5Y0z8GVWkSQJl8uFz+cjGAzS09Nj6PgBNXBIxc2+7i4qFAqoqsrh4SGhUIgXL14wPT1NKBQqx46MjNDf309/fz+dnZ1cvHgRl8tV3px3CpyNQyoyMJnKn7yiKDQ1NdHT08PKygr7+/usrKyU47q7uwkGg/T39+Pz+bDb7TXZrllTh5xEqQufzWbJZrPl81arlYaGhvJOo1N0RokTHXLmgpwh9d/L/Ap1QaqoC1JFXZAq6oJUURekip8VZrV7hviXUHdIFXVBqqgLUkVdkCrqglRRF6SK/wGkqOTGpsqraQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 72x72 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "im = Image.open(TEST_IMAGE_BW)\n",
    "ax = show_image(im, cmap=\"Greys\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "...and color images with standard `CHW` dim order..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "im2 = np.array(Image.open(TEST_IMAGE))\n",
    "ax = show_image(im2, figsize=(2,2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "...and color images with `HWC` dim order..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "im3 = torch.as_tensor(im2).permute(2,0,1)\n",
    "ax = show_image(im3, figsize=(2,2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@delegates(show_image, keep=True)\n",
    "def show_titled_image(o, **kwargs):\n",
    "    \"Call `show_image` destructuring `o` to `(img,title)`\"\n",
    "    show_image(o[0], title=str(o[1]), **kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAH4AAABpCAYAAAD88JerAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAABRAUlEQVR4nO39aYy1W3qeh11rfKc9VdVX9U1n7pHNJrtJidRA0qRMkbLGyBKiQEMkIHEEIwEy/AmQwAiEJECSP/kR5KcBZ1QgRE4sO4gQ2pYoibRoiqTYEkU2ye4+p8/wTTXs6Z3XlB9rn6OOEH6UTxtmi93roICqb++qs/d+3net57mf+74fkVLiO+vbb8nf6RfwnfU7s74T+G/T9Z3Af5uu7wT+23R9J/Dfpus7gf82Xd8J/Lfp+lci8EKInxZCbIUQxe/0a/ndsr7lAy+EeAP4ESABf+p39tX87lnf8oEH/jLwc8D/AfgrL3viaWf4Xwkhfl4IsRdC/C0hxPnpsR8TQrz/Lzz/HSHEHz59/9eEEH9TCPE3hBBHIcQvCSG+8C88938ihPjV0+7z7wkhytNjvyKE+JPf8FwjhLgRQnzxv6TP4L/09a9K4P+vp68/IoS4/y/x/P8W8AjwwP/uv8D/678G/N+Bc+CvA/+BEMJ8w+N/EfgjwCeATwP/zunf/0/AX/qG5/0x4GlK6Zf/C/y//6tdKaVv2S/ghwEH3Dv9/GXgf/SS5/808L/+hp8/B8yAAn4MeP9feP47wB8+ff/XgJ/7hsck8BT4kW947r/9DY//MeCrp+8fAUdgdfr5bwL/49/pz+9lX9/qd/xfAX4qpXRz+vmv89ts98B73/D91wED3PuX/P999LsppQi8Tw7qb/W3H52e+wT4WeDPCiE2wB8l71Dfskv/Tr+A32oJISrgzwFKCPHs9M8FsBFCfCGl9KXf4ldf/YbvXyPvGDdAB9Tf8PcVcPlb/a4QQgKvAE9e8re/8bH/I/BvkT/Tf5hS+uClb/B3eH0r3/F/Ggjk7fqLp6/vAv4B+Rz/rdZfEkJ8TghRA/9z4G+mlALwG0AphPjjp3P73yFfSN+4fo8Q4s8IITTwPwQmcmL54frvCSFeOSWM/1Pgb3zDY/8B8P3A/4B85n9Lr2/lwP8V4N9LKb2bUnr24Rfwvwf+4ik4///W/5lcATwDSuC/D5BS2gP/XeDfBT4g7wDv/wu/+7eA/wawBf6bwJ9JKblvePyvAz8FfO309b/88IGU0gD8+8CbwP/jY77n/8qW+N1ExBBC/DTwf0kp/bsf43f/GvDJlNJf+i0efwf4t1JK/8lL/sb/DPj0b/U3vpXWt+wZ/6/aOm3//23yTvEtv76Vt/p/ZZYQ4r9Dzvj/dkrp7/9Ov55/mfW7aqv/zvqXX9+5479N13cC/226Xprc/YO//4/SNB0Z2h3N6h6744CSsKwMr73xFje3LxiGASkki+UarQTOB47HA24aMbamLEvOzlYUZUHfjfzKr/xTdvs7rLUoYXj77d/kp//uf8LbX/kKUkiKssEoxaKueXj/Pv/mX/iLfOH7f4BnTz9gjpI3X3vM+dkZQgiOxz2zG1HKUJYlAClFQoj0/YBSkr7vESnQLDeUpWWxaLC25NmzZ5AkELm7fUZMgrq01IszlqslWiuEkOx2d5RlhXMzIOhHT11Y+tP7NtYwjiO3t9eUZUNZWOq64ebmORcXl7RtB0h2uz1nZ2fUdcFytSCEwPZuy/6wx9oCKcBoy3sfvEdTLzkctpyf32MYBpJQSKk5tAe8m2maBXW9IIWZ4ANFadjtDhz2R+q6RGvDi+sb/upf/cviYwV+nme67ojRhghcnK3pug5bWCDR1A3jMAGSaewJSmOLkmXTUJyfo4ykLCtSgnGcCMHx1lufYBgfopWkKEs+/dnP8IUv/iD/4d/69/l7f+en8G5CipJu6Lm+veNnf/rvcH5xwdn5hvPzK5arBiHg2bNnGGtYLte4eWSeR6qqJgRQEuqqJAmJLSpECgipsLbAWst+t0NKBUhSTKw3lxhrqKqKsiyJMRCCJ6WE0Yqu6xAohAAlElIJhmFCioRUC4qi4urqAV3bE2Ok7zvqesHd9pb16pxpGnnllYc0TY0Qgnme2e22TJNjuVjivWeaZqTSPHzwkLu7fLFJKTFGgxBIKThrCvoxYZTidtdiZGBZl5RlTVPP9N2A9wHvPd4NL73jX7rVKy0425yzWK65vb1h6AcGp0hYYkrUdU1KHikFtiiQSiKlZLFasNqsKMuKrusYh4lpmhn6lsIqHj18yHqzoWlqFk3Da6+9yo//xB/jh3/0DxEIpOgJPtIOPe987R1+9qf/DvfuXXJ+sSHGyO3dDUIIBIlxGKjqBUVRMk8DWmuEzBfgsXf0/cTb79+QkqCqKoZhYBgnYoiEMGOLiuVqzfn5OVVVEWPAufmjAAmpkEICAaUVZVkQY6RuSpAJITU+RLRWNE2DlBIQlGVJ0yzwYaYoLGfnK2yh6YeW/X4PaJSyAFhbUlYVPkSquqZpaparJc1iBUIggHHsMEXBcrlmdo6zZcUbrz7m0eOHjGNH13cslhUJQYiJ1erspYF/6R3fNDWuP+CT5NXHr+BDoCgTzaLEOUfRNJRVicDQ1DVlZRFC4r2n7wdiiKQk8TGgtMHYmhc3N7y1WtE0Nd4HwJGS5DOf/iSr5Z+n71q+9Av/CGM1CcFxGPnab/wmT95/l7KsaLsOJSX1usFNIwnB0I80TU1RFHTdESkV3gvC1PHeB+9zbAfOl4qh3zGNE+vNBbN3kALWKqy1SClxbkIISUoQY0JKjZKSxb0lIXjm2RNjxHvPctHQ1BWTA4lnHCYWiwXeO6RUpCRYr5Ycj0e00fT9wOFwhASChDaKGANGa/ZdjzUGP48c40xZVez3e1I6sliu8fOI1oZ5HqnrJfebBVopYgrc3d7h5og1BUJI1mvLe+8/Qf422dtLAx9jYI4a5yakkrTH/eksrQnBMbuZxWKJcw4hYbvdkpJAK4OxFuc9UoKxlqEfmaeJ2kDfdyyXS0IIGGNRMp+nr732Kn/iT/0Z3vv6O9zd3hCJuBiQIvH//Bv/N/7sX/jLvP7mWwgEN3e3KDxRGDabNbtjT11q6nrBk/ff4+tvf5V/9qVf5r2vfpWxbflPjcLakvVmw+M33uSVt97iu7/3i2idAyBEQimFmz1CSJzLO1kC2rZlsViiVEAIhfceIQRaG9w8MPkZqRQhRpqmRkpJVVcoJRFCcHN7jUAxzRPr9ZqUdD5GjCKJnFukBEprvHNUdcHFvStePH+CNpoQIxBoFg0XF+eEENjtDtxt7zBKo43E2IbJa0oTuH91jw+evPj4gfc+oo2kLOucTJA422yo6nxuu3kmxsA4jDgXMNowzR4vJ8axJyWomxopJGVhCG6m2VxAikghWC7z+RakIMRIUVa8+eYn+N4vfj9/56f+NonA5AdSTPzMz/wMzbLhT/+5v8Dl/UdobSiVRhUVpIT3nufPbnny7lf4lV/8Rb78pV/ETQ4hFAmBHAV96tne7nn6/jO+9PP/iH/8cz/HJz/7WT773Z/n0WtvYIwlJYFSknF0aG0wRrLbdQghWK1W9P1wOhIiSmkWy4aiLDgcdiglP9p5Ukq07Z5j21JVNW6eWK/PCNETQ6LvO8oy7zRNU3M4dFRlwyRGuvaIMZKry/u8887XuLi4YnYTl1dXeB955523iSlRlRXOOaxtuN3uCLLCGMtmvaLrp5cG/qUAzq/+6q+lGCMCTltqi5ICHyMpCawpAIFShqIwJOD25jkiOpK0rFYrUnB47yiqJUIK7m7vaOqKxWJJ1VQIIZimiRgD0+QIQfBPvvSP+d/+b/4X3G13RAR1USJFYllZfuKP/CT/5p//K2zOzpnGnnH03N1d8/TrX+Er//SXuXn6FD9OuNlBykQ9qTWkxBwiJAjaEKNAGsOiabi4vODNT3+KL/7A7+Pe1UOWyxrnPCF4iqJgHCcEgsWyYRxH3OwxxhJSwlqFIB8NRVGglGKaRo7HI+M4oqTBGAMi0Pc9ShYgIu2xw/uZ1XpNYUvGaWaeRpyfkVIRfEBK8D7RdnsuL+8zDhPb3RYhwGgNIienUgrKsqZrD8xuZLW+IPjAj/2hH/p4Wf1hvyeEiBBQ1RVdP2BtjTGWuirIPI6AD4mQEsM4UpUFcz9Q1kukkjgPCImUAqULuq5Dawm9JiI4O1udzsUPt07HG2+8wcPHj3lx/YKUBEFJkhDMs+I/+3v/AJTmT//X/zzt3XO+/Ku/ym986ZfY31wz9ROHccQ7j5ICrTTEhNKSwhRorbDGIrREKsMUBfM08fz5NV078O7X3ubzX/gCP/jDP8LZxQUpJZSSFIUlxgiQk8j5iBDQVBalNEII8v2TuL29YRxHiqJktVohpcK5mZQ0UkpSCvRdi0yeQgtSShy7nq7vcfNIXZXEJHHAus4V0tOnkffffxelLILAZn2Oi4p5HJjDRGkrkIJxniEJdrsdWv+WMf/tAy9USQiBRWU5P1szDgPzPKFkYrttAYG1hojGB8cw9GxWG7phxKoadIEIEj8N3L74gNXZQ15//Q2kkiQESShihKqqaNuWec7ba1EafuKP/FG+9rW32d7dMU4TQkpiSqQY+Mc/+zP4/Y7gZ26fPqHvemYf6MaJcXZ5GzQGJwNGGaSPOJEvhnkY0NajTOBs0ZCkYQyC4Dx3tzv+8c//AiFGfuJP/EkWi4aUYj5/laJt83s2RjO7CSETMY6k01EzTRNdl/MXpeTp3x1a5zpcSsl+v2O5WlMWBVJKhJQc257SWrq+IyVPUxcsV2eMU8/ddkuIkbpqkEoRY8L7GWtKvFIMg6IUmsN+S9+3WFOx3mzwbvz4gR/GGSUCJI1UCmsNWiuqusTvHCkJpjnQdkfqxYqmrjFFxf37j3BRoqREWk9drehVJAnF1588RWnFo/sPkcLj3Iy1lnGcuLu75Wy9QknFZz/3BR699jq73R0ueDQSouR8ueGiKXn7134VHyP9NDNOE7PzxBSQQiGlzAnRqQwT0iIFCCFQWpDTds88Dmg1s2oWKCNwQuNd4Ff+8T/BaMXv+9d+NNfTShJjYugnpFIURYE16pT5K0ggjaGua6qy4HDMoE1RlMQYcbMnMeeds8okIOdd3lG0QSuBrUqqusK5ibqq6IeeFy+uSQmKoqCuam7vrlkszvB+ZnYTUgjwPXWxxk+WqlpgtGLoD/jw8h7MSwNfWp23RqUIwSOkws+e3fYOIQTNoiGhqOuGxaJBSoExkpAUuEC7v6YpC9wUqBZntP3ANI08PrvPZlVjjGKaJnbbHdZaLi7OUKR8XpaWH/3RP8S7X/tNhrbHKsXVesFZU3G33eO8J6REO074GDFCorRBSUVKkcE5hIOoDbIyRCKzH7HGYo1CREkIkGIkHFrqJWipqOqaJAW//k9+hc3mjLc+971sNiuKUhMjHI4ttiypSkuMgRhz9SMQGGPw3qCkxhhNVeX8IEWPNpZpGjHaoLVmdo4QwbnENE503YBSAmst2/2B6+trVsslTbOkHzqIifX6nLbrKMsFAo8UgWVtGYYerTWr1YZxHBi6A+v1N1HHb++uubh3hXcTm7jM55mM1MUSqcRH25gyBudmuq7j3sUFCfBDi1aWZ9uJYZp583HNvfMVl+dryipf2cdjj3MBqRRGG6qyxI0tznkqq/nsZz/HZz/33fzql36Zx2drVmXFze5ASgGJYPYBF0LeUqUg+IhSAi0lSisKpdFS0k0j5+s1MUQGNxMQ+BhYmHx2K6MIIaEIjO0eWzmMWvPrv/wLLC8uWG+WCAFFoWlizTzNKJHP0BAjgpzhSylRSmNsRjbn05mbS0aHNmU+e1MCIrOPdN1AXSiMVmhTMDtHDInlco0yFpSmqFeQIrEfqGrDYXfNenPO0I8UtgYRsWXF4ThQ1w0xBs7Pv4nAq9Aj40Rpl0iVUatxmHE+MI2B2krqqmSaHcHPkFKu9esGoxW2rHGMbFY1y2WNMRrvPfv9luAjQmoQJn9IbiZhsVXDODuKwnLv3gV/8A/8EOH2mjBN7PuR0c1YJXARBh+IMaEkp0oDrFQQIyIBWqO0RSB4cbejbhaQEqUBrTVKCJLUJGVyhky+aMZjy9h1RD/Q3T6nsN+TEzgpMVpgTb7bi6LAnnIo5zK4o3UGhFLKtb5QYHRJ8J7bY6A2gXnYI6XOZVh/jRWGwmiiT4gkidGRwoCPnlhUjFNgmkZiEqAstsg3jlKGRGC3vaOuV0xzZLNeslot0frlHJuXPrq+fA1bl6jTVm9tDpIUglVTU1clUkmEyBBnXVfEFFFSUS4qtJY8rkukhHEYaY9HbFGilMXNPfvtC2y5oLSGvt1RL1bEskKqgpR63Nxz++R9hnHk2A2nuysxRYGPiQjEBAqFjwEhIrObsMqghMCFiJQZiNG2QMSI0orZB0xRMUuNkBKZJB6JVDr3EJQmhsDxbs8v/4O/x8WDR7zxyU+DEEzDgBCCxWp9An5ASnVK1BQKTrCtRmnN3a5nVRUoqahLjSQglUUIweF4BCmo6gZ3uAUpEeUarQyH7o6ufcqrdUNpFCIkYhJIU5DCmm7/nIuzc1brFUYXHNsDRkYWTYUQkvc/+IDPf/7TH/OO15ab5x9QNmum4cjF5X0QCUSkKAxSW4RICBK2KLHWYq3BWosQ5CRknvDeI6WmqpeE4CAlrK2o6wgiIgjsbp4jtUHrgoRgnBw/+x//bX7pH/5n7NqB0TmcdxRaIYUgJogpobXGx4BWGaMstKGwNpdy8nQXK829dZ1rbB8ZZ8ccAmKesUaDkqQQkNagVcbmdVmejqyR//xv/79IP/nHOLv/kLqu8fOYgadTnZ9SYhxHhJRoJUgxQ7JKSjZ1gZACpRTrQtAeOhDgA5TWYNUSawrM+RXT5LBFgQ+J1eYcYw1SJNw8oUSitAJbGcZ2ZlE3zPPMixfPkVKw2WwYhoH333uXBMyze1loXx74EBzdYU/dbEhJZgiSvK2N45Bbq1KyWq9zc0QIYox07ZF5ntHaYgtLUZY4n/DB4yZHjDNKF2hTIEREScH9V94gIhmngRACX/31L/PzP/Mz3OwPzCGcYEvyBRUiEXJWCwjyvyEEhEicZ5aloi4K7p9vqIzi8YNLjLHsupHnt3tCjJRas6gthZYYrZA4tMzvW8gMSNXlgjB2fOnv/hQXr3+CVz/1aZabc4bJYwuDm2equsH7gCCRYq79IX8WxiggndDAkffef8JqtaQoa1KYOT57l76suP/amwgP4zQTY+LQHrm8uDzlFhbvJqq6YXYzfu5ZrZcopej7iXnyzNEhgKZZIKVhGF/enfttA//4jU8ipAIiIKjqkhASm83Z6QiYTyiXA0TuWydJUSwQMrd2wROSoDQS2zTsj6BIkHJA58kTQmAYj1hjGYaRn/1P/2PudkdSEojThxhjxHlJYfQp4PnODzERiWip0FKwqkrevH/Oo/uXlNYQomA4tnRCoauG+xdrop8gREL0tEdHFAI3zVhrKApLN7cYZRnGhNaKdNfy9lff41f+859nudlQNgsuX3mFs8tLpNLMfUtRVZxf3ceWNUJpmrpBG/VR42q727NanWE0lIUlBkWx3LA4O0dKRdePKCkpS8O9i0tsoZnnmeAniqLA2IK7u30uS1XuoWglCUZSVUvcNDBOPQhJVVUfP/AX5xfEFDHGkFJkHEekECijOB62pARSKaqyRmmL1pqqqtje3aKNQQhJ27aoEwbgg0al3HYlaYoyB1kqjVSathtovWd7/Zx33/4qsw8gBSJJSOBCQEqBDBlCLrRGIBACtMywbGU0n3/9IauqoN3veTE4pLEYrUkJ/BBwbiJ6R11VSARRaGJKeGGIDmRpCdoQgsf3IylEqqrMcC89QzeireHp199BSMk4TjB1LOqSzdUVjz/9GV77zOcQ4j56NlR1RQgeow1SQlMZQkxoU3Dx8FWkUmz7iCxWJNczjyNN05ClAx4/tyya6qNqoCwLtnd3uBAxWmJtwd3tNYtFyTw5jJUMQ/fxA3+3vSaEmBMXIVBSU5QlQogM3WpDjB5rC+bZo42mLKtMHkCgpGKePX2/5/z8ghDyXaqVILiRGE1G/mLMzZ0kmKeRp+++S9u2xJQTOBCElAWeMUbmlJBCEpUknnCKdVnwYLPi/mZJnB0v+pHJBdppzq1Va9C2AmlIKEY/Mxw7Clvk9nCK6BP8KoYJaQxTjIzThFUSxnxulrMlpUTT1CAymjh1Lf3+jqNMHK5fcP3O2zz99V/jM7//h3njc19AKYXRGqUM3kcgYkQ+onqvEN6zLCSytByODiJ0w4z3Lc456rrGFAXjMBK8p64tWkakLhhmT9tHCmtR0kDyHA89m/OXywVfGvi6WiGVIsVAEoLdoUXohHcdZbEhJg8p0g9DLmVmTVkGtM7KYq01dVUwdEfa4571eoU2Fh8FPgrcPKCkxFjL8bDFSIUTmpsn7+KniZDiR5k75EZIiOkEgWbCQYyJ86bi8w/vce9sSTs6Dp1jCoHBOUJM4CZETNSmJo4TQUjm09GRmFFS4WJEyIhShsl7FDC7mRhhGnvqqsL7wBQCfp6Yhh5tS2bv0DESfMCLxDyOJGV4/+336Nu/ze3zF3z29/wgV48eUdf16X1E5nlGCkkQAecSViVSEiybgpQs4zgSfaKwJXVdo7VhHLYgIlVdUZZ5FwkhsqwSIdXMPlDWKw7dLYf97psIfF3jvcOlGYEm+AGra0pTU5QFMSSCiIy9oyo1u8ORqspnUXtoCTFRlBXn52eEFLG2QhuBcBFhIjF4hNR03cB+v8dai58Cx90dzgdSTAglEVKcLoB8BQghAJHLqsry6QcXrJYLrncdT/ctLiaM0ozeI6SkQHB9PHBuSpbNkm6cENqgdSIIkdu2ypBEPlJCSsgQKWzBMI6EGPEhg0ZJCBKSbpoR44xzE01RYouCbn+HEhVeTvgkuLvZ0v3Dn+HFu2/zvT/yY7z5Xd+D0gqAYehpmiW11USt8CFD4CBJSYJwVM2CFBPGGKZxYJpn6qoghkBICu883o0UtmDfTyyqgraNmKIhq8M/ZuBzslVSVRVSaOAcAaxWGcmKMTJPI5WBrp/yneNcPoP8HcrYzASREj/lWt+5wDhOH3Huur5jmkYWixVde6BtdwghMj4QAnAKeowkcuIOiXRisrx1vmRVljzdHnm6O7IfRprC4lTCxYhVidY5dv1AMke0gBAFKQWUthiT8wSpMr9NAWEaUSf2jaoqDt4xDQNGaVRRQPAooxn6nmHo0MmTjGU/zlhjWVYQnccrxTwdORx+g7mf6PcH3vz891IuVpRlfSoJAzF6xm5HYS2mWp/KYk0IgXFyGGPZbm+JIVIsaqZpxDnHNPkTUJNYLwpEDJRFbjV3XfvxA58iPHn6Ppv1ms3ZOZKE1IoQPSIKhmHgydd/nbNacv+tL+CTZBg8dV1SFAUCQMhcV+ucyFV1BYyYoia4GSEUWim68UjfHVEiUS8zoVIIQQDCh+WcyHi6khIfI+uyYFMVvNgfuRtmDuOMCxEfE0KBlAIhJMIU1AuNC55DP6LLisSpiWQsMXhIuQIRJGRKKO/wbkakRG0LZgQxBPAObS3ee4ZpYBh6wjSgjWH2kZvjgSRgsVjhYoFVirv9EfH1d5mmge544K3v+z3cu7wizCNVs2AOgmZ5gQ8BHyLddosQAmMs9sQQmueZmCLDMOZEVUtS0vjg+cq7z7m8d0llJbMP9P2OMPcfP/BunijSSEpr3OyoCksMLuPrUjLPU8agVZO33xNkGWOkaRZ0XQdCEYJDaUsM+cOr6wbvZryfco7Qt3Rde0oiLavzSwqtOE6BGEOuHqTC+wxKxJjQUnJWWY79wO3gOUwzowuMLn9Atc+NkWQMdd2Am2j3O4wy2BAQQmKUyiBNjDmPSAFF4nA8UhcFEVBS0NR1PmaUIoSYz1xjaLsjISVuuwEtBEJbfDJUUVEJjY6RyQcicOwG0otbyl//MucPH7JarVFS0PUDUkoiKiOAQlCWBSFE9vsdZZkpXFVVsVmf5WPHO5II+KBIbuJstSLNPbpagJVoWdGfcI+PFXhZbKiVQunM+/JoyrLGDUd2+zuENJxfPiKR6PoJIQWLpmSePcYa5m3Gk2OSlLqgKnPfvutaiDkxbNsDd3c31FXFolmzO7SMk8dqjZQ5w02kfGEJcTrfIYRICIH9EGnnSEyZvmWNobQGmRLT7CiqBT4l2q4jpMicIioJZEwZB3Au00l8Bm+mMXPoUgy5tyAkqT1SFCUJgZKGqqyIwGZ9RnQO72f62dEPI3VZoI2hqhf59aZAEpJ+ntGTZn97y3tf/lUuHj6mUALTrFC2ppugURDDTN3UdF1HUeQKydoCrQzjNKBUrpy886Q4IjBsNme4ecD5yDwNKGUxRfnSwL+Ui9n3B9774CnPX1zT9z1DKPLXNNONDltUrFbnuCg4Hg4EH3HOMQ4dMUastTg3sVougcR+v+Pm5pp5GnPd7D3WSC7OL1ivzzl2M+PkMdWC8lQ3+3/hyo0p/yylRJIy/z06Ju+YTkGMITJ6j9SSkCJ3ux39OIIpcCHRDR1lYZAxEPyct3YSfdfS9j3BBw7tga7viLNjGAbmviXOIyp5kncsFg2XDx5z7/4jHlw+5Gy5JKXEME5oMgHDh4QPCSk4kTETQz/w9J232V6/QBUFxlqCm7EqomQAkfsJfdfhfT7D99trtncvsLZAqSzgGOcBWyjKsiGnuolpHJBSMfZH3PRNbPW/9uUvY7Xh/v0HVGUDsidOA8EHFosNWhuUNgQ3slguWCyWmfuQMqyrtCYGz932DuccWkoKLSF6os/t1Lqqkark2Ytrru+OpDAzDh2FPLVXM00OTt3MDymCMSX62VNqifOetp8JKRGtQUiB85F1UZKEoJ/HTNYIns1iSVUUmQeoNYUx+BCY5xEJaKW461pS8BTGMLgBQkBRwewgeIyShLGgWp/x6htvcrxdsNguuG57+nFAFBVlsySEiJUCJQVRJlAZuBlGx9jncjDGxDT2VPUS52Lm0p3eY06GPcfDkZgiq00G0+pmyTxNHI/bk+iiRNkFRaXp2j22sAzjN4HVf89nP52DFxNIRV0Z2m7g/Pz8RC9WlGXJcvU9hJgz1L4/JTwh0DSLjEknaOoGCLSHPTEm6qYBJP0wcWxbrncjT256TGp574MXSKVRpwZQVrb8c6xeiBz47TRzJS2EQEoBHxMhhNygiAkh4DiO7A4HYnCURcE0Wc5WawpbcGhbSq1RErphgOiRQp6AIhjmCS01wzQSg6epGlKMRO/xY89ifYata7S8whQlD3d7vvzu1zlME4+kRGRoE11Y0jDhUsSHhDaGxXrJ0LcEWXF3mFjMiUdXFxijObYtzgXKSqO04f6jV5Ey8x9S9PgQ8W5muVwyz+G0g8YTF8AQg0cp//EDXzc1ZZmJ+lpLbGE4Mxql5Il8mOj7lnmaGYce5yMIxWKxyCIFkaHVvj/S7fYYYzKG3TQgEtPomCaHNoars5o0HzkcFC6CblZoeZOzbLJq5kM2q9SCkCLd7Om1pDIKOWUusPMemRKF0Tgf6MeJru8ptCSFnFf44HBzpj4d2gMxeKyQ7I4HpBB4IMSAH1xOLEkcY6Z1FVIxTTNl1RDdjBAykyXKksv1Gb/Ouxy6Hj/P+W4vKnzKrew4TciyYHV+zvriAYvlWebZRY8SGRGUUtC3R0IYGUdBNziWTXUKfEAQsbrANDVlVdJ1AwJJiJ6uPWaxx+qcaXr+8QO/XNbEEBEi4d3MPA3Mzn0kKKjKU8KjDFf3H7DdbvE+opTK7VI/MY8D09gzz466WaGUZpxGpMjNC20LQkqUhQbfs6gNq1VN6y6pnrzPYfLE6DPNKcV8x504AT4EdqPj0cJipMCdqFRRSkiJyTm2+x0hOKQtEYBSEikUzrsTbRzavieFmCuCE8VMCEGKER8DVmkEcOw7rBQUhSX4meBmUsw8hTAIFoWhLiwRgU8JkyBGMLZgnB1J5Jzj7OqKusmceCXh9YeZ0RtiIsWcoFlrUTarjfpxYrNek2JimkZmF6nKKtOxneNue0dZarRWGLvgeNgjpXlZaF8e+K5tP9KCKZWJBnVdoJRGa0OIuSM2jD1KZbJh13WQAsNwhFPdKaWhXhQobWjbI1rbrE+TAjePBDexu33B+eUjdtsdm82G7d0tUltI7UmKlV9T/LD1KcAl6F2gc5HKaKaQiClmNi4wjiNd32FULpMEMDuPj4Ha1BluVfkj6OcJH/JxJUSup2NKmNNFFKNE2kQ7DNRVhZACoWSu7WPuNBoJlVYcpiGzbTebjEaGkLPoFNFS8PjNt2iaBSlB1/kTZXumLjJUG6LgbHWWBZh+JkqT2UVFidSaafI4n3Bzz25/QClJ109UVcmiKpmmzJJ62XppVj+7iBAGpQuG0dN1ucertaXterzL54h3nmPbUjcLisIgiLSHPW52CCkpq4q6XtD3HTHC8XhgdjPDMHJzc82TJ++dcGd/kl1JlqsNZrGmthpBZt5APttTAiH/eVl3N8yUSlCc+AJGZgLkOGehRm4NgfOBbujZ7nbs2gOVzdtrQiClxIdIiAkfYpZbx5Dr95RzDRcig/N0s2NOAlMvEVLSHQ9MU2bgVkXG75USFGWJlIJpnnJPQisev/E6b3z2uzK71mg2Z+cImenbQgrmecqklrJESg0EVJozK/j0d0JMudcRwJpM014sFjx48JBhGJnnKe+gL1m/TT8+0LZHqqpm6DsgUlULQujzXaglCFiulqSYCN4hhWAcB5pmQYiSpsznX9d1SCGwRgEGKQ13t7cIBH0/sNmcIaVm0eSGRFUWnF1eoaKnn77O5IbMiA2ZKKmTwmpFkCKXaCGyKBRqThQyXyrjPCOA0qgss0oJcZIREyLBO1ZV1r7n4+eExcd4UuOCErl0dCGihaTUCkVCCEU3OcI4Mh0PqOCRxrIsC1II+XlaMY0TU99RWMvZZsUXfuiH0dbQtccTTGxyUyvlZHQaRwQZV5Aq3zTe+YzxC3I1YjXDMOLmKbekFVgNXXvg5uY5ISTWZy+3/H25oCJ5ymoBIjI7jzGGmATtYcdqucot1RBJKWeWiYgkorSmGybqekGzWLLbbSFBVdfM80Slc6errisQivOLE2GwadBas1wucPNEvdpg9Ekx8sFTDmnEnWDNoCRa5tTPhUA3BXRlWFQFKeb638eci5TWEBJoIdBSk067hxICYmBZWKYmZ+yTcyQhCDFgtUYp9dGOURrNqq643GyoyoLoJoa+Zxo7lMtNlbPVCvPimpQSWkv6fia4EWki3/ODP8Znvu/7STEfgcv1+kTSCCdYNnPlhRKM43gyTEjYU9mXq438XCUiuiqIIaJNgdaWm+tbUso5yDR9E/147ydCqCirggf3HyCkYnJZ1VGWJaSZ9nhgmmd8iDQnbbeKkcl5lotlJgQISdcdObMFRVHTdQeEkJRVyeQi0+xIJJxzzMNAVVZYa1hvztgDs7acrxY5kx9nnPeUJp/bSkKQGcKdfO6glVp81PtXJxKkhiywUJYxJJ5ut+z2W1ZFRvmUyMydQUp8CLiQe+1KyhN6CMPseH48ctP2NPuWR6+9waJeUGvF7vo5TfSosialhC2KnOBOHctC8vt//Mf5gR/7cVarDTc3z0kElBQn+JuTBl+wWK2YpomUEtM0o7XO2jskQmjm2ePcRFmUOD/n7mNRcjx0uUyuFzzdjhjzctHkSwN/ef8hx/2eaZQolbBWUJf5A/d+YmiPJ8KjoSyLk6xYUZQVZhwZxi4DOVKhhGC3y4DDarWmbY/5+0VN8Ge01hBDoH/+NlTnnF9c8t77H3A87rm4fEBXVvj0HoKW0TnmEDPAIwXqVG7GCL3zNEWFVtnRQvAh6iPwKaLxLJs13jsOxx3zIFFCYrSmKksqo3H5BMsaPwT9OGbatXNcXdxje9jTbu9Y3X8NaaFQhrJZ4BBZeCJyRiJSYlVqfuDf+JN88cd+krPzi5ybCIlSJrek+wP37p2RYmI+IY9KKdwpf+r7HilH6mqBVIKqshijUCqzhorC5CNintBao4uC+8qg4zcR+Kqqid7RdiM+zDSLC4J3zPOIc3Mu0RYbpMrEiKqsT540itVqzTw7fMjbVtceMigyORKaRbNgf9hBCqxWK7wPzNPE/bc+j/OOaZp5+PA+V5f3ePH8hmeArm6pE4h+ZPYOdyI2FlpitaKbc087iwcTIQaMUtgTCJUSXN67hypKggtM88zusKU0uXFjtKHRkkIVIHINb6RgyvorfMyEUVuU/PiP/ATry/v4aeDtr/4m09BRbTasVysWdY0SgJ/41Be/wA/8xB+nqheUZXnSxRekNBOj52yzQArB4D2zcxRaUJaWMI8koaiqmmmaePb8CevVGluUtO0RISRV1VDXNdvtHQIJMlFXJcvaMI/2pYH/bbD6EVs29ENLCJ7rF89wbmQYBoTQSG0JMUCComgYHZRVPscPhz3z5JnGme12y+Q8pijZbM7x3tEPPXVVZwKlmzg722CspqwrmmbJNI1s1ucsFiuSLBmHHmlLglD0IRKlYkqJ0QekVFilkClX5t3s/zkDV5CxchFZ1DWrxZphHLneHzk7v8SlnO3PMSFl5q9ZJamUotaaQmusPOUyMgs5fv8f+FHUw0/wtZsD7z99yuXZBdE7mkWDPfETC6NYbpb8/j/xZynrxSkXyuSTGDIYNXQdMYD3Aecjfp5OXUIyt2Gec61vCjabM3wIHPY7UsqSrXFsGcfseyOVYLls6NotMUaePnv68e945zyCyNXVFcfdHQBt12NMwThNtIc9pqzZrNc4l3V2KUZ2u32mFUlJFJIHD67yFQkMw8huf8ft7cRqvc6drmlgnrOdyTxPtMcjy+Waru3wwSOS47VHD5i9Y5hmXluumKaB/eFIN8/E6FgUGcAQITC5wMqCkSqrUWKgNIq273h474p6veDZsxd4MpQsY2b7KCnRMu/zmcSRjyi1qHm6P/Dag8f8wS/+AJs3PsHXtz1vffq7eXVjePLPvsTudoHWiqlvSc7RlAWf/L7v5+FrrwOS4+TYaEvX7nHeoZWi3d8RQmSxXFHqSBIRoy3OO0xVUlSWYU689/yGBxcrqsoQrc0X6jQRYuDm5pppnLi8ujjxHxQ3t/vsn/NxA5/CTDd0SKkpjSEJRT8HYgBjS+rFqbaOiWEYCN4zntgrx2O+8q4ePM4ImM8SaG0N5xf3qesWIRSzm9Eqb8VduyOlSFU1HA4HhNQcupHHj66Q4opZSO5d3COGwNOnT4gIaDvGoWMOgUrLvAukjGcLkTl5xEhlCg7DwPvvfY2rzRkLDbeHgcbaE4cgURYFViukMMiTxKpUmtJ7hhD5rk9/hjc/+Rl+7XnP5TqyNB4lK7786/+Uhw/uE31EW4OSgqpZ8NZ3fx4QjENPUxikFIzTdNqJFKvzS5SUTNNM1+45HA5chkjZ1MQAIYGSkmVdEZwnCUhJYmxxKv0mBJKilBwPHbbI3AMpFIdvhoFzd/ucaQ4sl8u8TSXFcrUihkR7PBC8o1xeYGxBVZWMQ7YMMdawWp3Rdy1TsFjpebG9ozQZpz+2Hftjx8OLM5o619FSSYZeIYSlbTu6/shy2fDZxRuM48Q8T7zyyhu0xwO3N9dcXl4ReYEQgk4KfPTURnOcQ0b1Rc7oE3AYR65WFY1RfPndtxnHntcuH7CUmrsuUZQ1UUjOS0uRsgOIJSdbVgoWtmC93mCdY//iff717/tBvDEcji0/81P/EX6eWFclLjjWq4rGWpqm4t6jV1AqEywQOQ9S6p9/5HWdLVWMtSgtaZaZnCGl5G67Z9k0zPOAOXkExRTYH3Y8uH8f7yJCQl01DEPPOPT0Q4/VKhtLxZf3438blm2NLiRlVWOsziYF44g1BVWzQhYLSmupLWglODqPQiKjpygM3SCYhhZZGKSUHLoOjUOTOFstiSkhlaaQcDhsKYoaENSNoO1aFosFXdfTtiNd12OtIkSYQ+K1Nz+BMBVDu6dtD8T9LTZbSiGEoHee0hiGaWZ0nmf7jk1VwpD46tOnvPPiBfcvLkghshCKRd1wtj6nTIG+76iMIboJFWaKsmJ59QpCG27bI7/wC/+Q7X7Pdr/DjR3rpsYWBfQj9YPHVMWXWN+7QJzMEOzJfDGGzOxVusDYrNTJM2ICdbPIVc2UW79nmw1CCMZppiwMx+OOqqxYL2rmqeewOyCUykYStsgAWswE126YCP6b6M6FlLfgEBK1KbP5X4gkcvuz0YnCxBPC16G0YR57QtRYIVmvMkAxTSOPry7Y7w/EMNHUJSlBWVVIkT1jrC0Zxym3FceRq6uMPA3jRFEa5rlECsFmk6irgpACV5dXiMt7xLnny7/4c8gQMCKPlTic1DlSCkQS7PqRdVWihSSKRAiRp9fXVDb3DbTIOoCq0Fl8GRJWFMQxIE1J0SxRdc04TvTTyOF4oO2OqBRpSktpJcoLHrz5CdZ1zb2HD1lvslT5Q/JoBl8iMGN1yTDOuWuHYThuUUJQFRXOS8ZhQmlN37c0VUlpcg2fXT08QmaKlveRlDx1k/sHx+MRLQx9v39p4F+a1d9tb3n65H2mccJ7x8W9S5Q+2aBNUz7LysyyCT53loSy9FHTTZFEZp1w6oNZq1mtN9iyQuiCqiyZpsw0kSr/HTcNaCVJaLa7I1Yk6rKgbmrWmw33r65YLJfEEHj86D6vv/YK85wNFAW5qfJhQyaRgREpZE7vU6KyhnT6Twl56u1HiAFBwNiSxWJJU1XZxVIKiqqhqEpMUVBYw3F3x/72GuYJHR2rRcXY7klCc3j2Hm+9+SqXj19lGDqGoafrWrq25di22T+obk4CDojRQ/I4H+mGiYRknh37/R3jOLFerTOraXY8f/6ctu9R2mCNyZ4CVUVVlZn7qCV1XfP8+gVt93Lk7qWB396+ABLaZuQoRrJmjix0TCnLhKdpyhy4mOlUy6pg3438+tefQEqkkB2dSDBPE9ZozjfrzKohgTAIkSirLMUy2uSzTefGhVSKqspqXKkU2hheefwqTdPw4sVz+vZI248EwKgsUflQVPlhpm61JiA4qwsKrSiMwmiZHS59wDnHcXeHBIqypqkqlssVy7MLmtUqE0BigBQolST6ETePGCWpCsM0zXhZ8P47T3j9E5/i3uPXCDHDrVXVUBQlxUlRnMGjIzEGtNZIkWXczfriZI4IMWSpVz9LVLHk7PySx6+8QlVWWZEr5EmezWkXUSepW+L+1X3Kovn4gV8sNzx8/CYJxe3Nc54+fUpR1Ljgs32oktze3hIjSCXouzbbm009l+uKT796nxj8CRkXuYwxFmtLikIzjx1uzmRFKbMDlPMzsxvRSmCMwCWF0paiqPAhMEyei/MLlFLcXD9HK4U1BdPJHSOzZyVaZactUr7rBYLRB2prKAuTOfMyP0fK3BT58N+0EpRVtjtZNjV1XWeblZQwAqqm5t7mjGVdcXmxybIyU+JQzFFw+/yOf/Jzf59pnE5tXtBaoXVWzkqZfXSEyKzdYcgkSkHOAaSU1IslhdWUJqFV+oiFrDVoY5GqIESfHUC0IcbAdruj77JO4fzi4uMHvllssEYxjh3vPrnm+YsbhnHk8uoB2uZS7O7uDsiM1hAcZVUzzSNuOKDShDaaqm7QpmC1WlGVJdYa+vZASomqqrPhQkonZWhgGGaci4CkrgqMMTx//gFKaS4uziirgn5oqeoGWzbUzQIlJf3kMVIghfjnnTb4CEJtJ8dxmLhoakpraQqDVTLX6lISImhJ7qyJBDGgTU6ejMwXU5wH3PGOGBzrpuLhg0t8iMxC0w0zIUYmH/nga18hnOjjfhqIwRFD+MhE4XBscScy5YcS82maGYZ8Q2W1a0KrvLuOY59fnylJMdEPI0plPZ4xlvbYMY4DQgqmmM0nP/4dv1gwdkcO1+9TCc/jh/dPtmQz9+5dcjjsMMayaFY0dcN6c4+ubzE606+qxQalPjwmcpbZNAvcnJkjUhlkchQmW5Gebc4wtmBwgdFFEJlaHKPHmFwybtZL7m5v0ae7JgTH2fkFm2XDYZqJQG1UDpSQJ1+a/DZjjNz0A7VVrKoCq7O4k5R1cuM8IlLAGkkhwSqVe+om7xCnNBxJwhpJXRegNNd3R17cbHn25AlT1+f8Qhj64yG3UesFnI7EoT/ks7jK5o7DMJxKZajqkqKwCCkJIeJDpO96xnHg3r0LmlP5F6JHyXjCT3pub284HPdobVhtLmgK+xFf4bdaL2fgzJG7m2uOT75OTJLleg1sWK+XJwlv7gy148z7HzzBKMXjh/coS5sZOgl8yBi50YqqqkgpcjjsSUng/ExVVISQW5d1XVGcJNdD1zEOR+aQtWOvvfY6WiuePn2f6GekgNVqzdh13O72rKuC59sDu8GxKk2+m7VidD43dLQ5UbayiUJlNcduzOWW/rAssmipEQmS9/i5p5YrjLVIY3PbNDgKLanLgovzDb/xzlPGORM2nr14wbJQfM9nPsunPv+9XD54TDhBweMYSWSwJoRttl2RmihETvZODZ4sKgFrC4QQtMcD7W7HYb9jvbmkPPnertdnVGXJ3d0NQz/mhHS5YfaRcCJcf+zA/8KX3+aNe0suX/8UVinOLh+yWa8wRvPi+ROkUJRFRRKC+1eXEAOFLT964U+vd3z1gzs++9p9rMlvaL/fQsqtUomn61ukyt2mrtujtWW9qrFG46YeJaBabVBS8uSDd/HOs1idMw9Hhn7PvfuX9McjMgWsVrSToykMRskT3enD9q06gTqCylp6n922Llcb7m3OUSlmTaBStLtb5ik3lpJUFEKTgLJqMIs16bhD6WxA/P71DebkdddPI4tiwTCMHLcvQEBVVmTDiOx6XVbNKWnVp87badMVGQF1zjH0XW6KNQs2Z+cnLl6gsOYEBkmaxtJ1HX3fMU49Dx48oCgKypg7kIfDN+GI8blX71EaxXL1AK0kQuSa8b33ntAej1xeXtF2e+p6wfm6oe8O9O2W9dllhkqF4vJswXpZUdUF8zhkcwVpcdOEUorkAwJFIlHXa47HPd4fqcqG5WbDNHSkFOi6jq47cn5+n8MxO0wOuxv63ZblosxmwEZxnAPbfmRTFFRWUSqBTxDIW35jLFIoIoGQQCpNSLAoa4yt8h12d41zuUEyjI72g+ekGHjw4CGXr30iI3BC4H1kdoHb9o6F1iy0ZJgm7g5H7rY7vE9olZ1CptkxTgP36k3O5gX/P/YxnPz9hMzIZ2MbtDakFFgsGryPHNojSmrqZoGTjt12h3O5nHTzxOxjvqj7EV1tPn7g5/5AublCKotSUFXZv61tj5RVc7r6sp516DvcNGHL7LP24tlzog+8cu/hRzy8w/FASln2rG1B8J5pnrE2Z6jjnJ2tUoK+OyAS1PUC52b6vmW1zsJC52aU0lT1muXqjPd/858RYk6CSpMZMwjBsszYe6kVKUZQmrIsOQwTN12Hcw4/T5mdqhVNWdBtX9DNDkJEa0skZjMjazm7uMfi/AKpFYfdlru2JSrN+WrF5WpFWZSMcWaaj5TLZXbbjIm6UpSFZrO+yHRsLBDZHzo268VHEzGU1LmZZexHTOXd7sg0ZSJlVa+4ub7J9KxTzqCVxgVBnAP90DFVFdPQ8uJm5Ae++MmPF/j791+hGwcUjvX6jHka2d7eEXzuXSeRQYQUZqZxZG7vkKZkt99TNytAIGXKIoHDjuPxiDElzWLBPLmsP9uckVLmsSulSMnjAlRFRdcekN7hQ2aihgBpHhnHgdVyne3DEzSr82wLctLSCwTmRKIoteLB+ZrNq29QXTygWKz5yq/8Ms9+6ZcQQjLOM13X8/hsiZERryRls6Eoa0QKqORoosM2i3xnpkS1PsdUFduv/iZDv2dKETfPPHr0iD//V/9tNps1y/MrlJIYW2a2rsluGN5nubiQEltnP7p5HnMZZw3DnFu3m6qkbbPZozGW4DOtfbPZcDwcmaaB43HP2dk5i+WK4EPuW3Q9WiVq9U1s9drAK+f3Sclze/Oc4D1GwqOHD06uVXnOi3eGWhUUZd6ehBTZNCEE6kYRg2e/3yGEIobINOWkKpHQSp3oV5HVcsHoBCJkiXOzXENwTPPEOI+0/XRK6jb0fU973ON94MXT95l9wCeojCFJQQonBSySWC558D2/l6tHr1FVNfvdlvSLv/RReTVMPdf7I9tDz1lVsVqesVifoaoiK1roef7iCXG3Zf3IgQZlLJ/83u/l8Xd9jvd+89d48cH7CBm5d/8hr73+OgGJUApB+IgHN88un+lCcnMcOV+WHwEw1mbTxLpQKFnnpkvf56qgKJjnPNTh2E9UTUNRlvT9QD9MCNljJNkEMcwUy4aV+CYCv1jUDP2R3e4Wa0sePXrMcXdNZUAwneRE+ZxMSWNPfu3ORaRMVHWe07LfbYkhe7He3V4zDNA0S3yIbHe3GF2e6MMOvMvIoKpYVAV3N89JwiBEdn66vn6eWTbjwHtv/wbKWF68+3VCjIwhoVSiOrFXjdZEJPM0UhhLXVUUpeLVt96iqSv2/cQwjRTW8ivvvMtFveD8k99NcfUYlEGVJco6hoODaab50K7VBy4fXPHoM59BCPjJP/6nmIaOruu4evwKpqqpjSWEkB1F3ExKAWuzEUOIkbNFiSTRti3DMOCcQcpsDVfYkufPnmUULyYEkrpuTsrZRNf1KCm5vHzA02dP6fs2+wDoGqstIUJhvwnXq/3dLYe2JSW4/+CcoW8Z5oQpi2zi6yZcv0Npm79k7q7FlM8fo7Ntx2G/wxYVMXoEnsIu2G5vaZolyQukCHg3sfWJqTtSlgXL5YrD4YaQBIfb5whTIJPn7Ows9/YlfPK7vpfrZ095GjxWKVIKHKdsXripyqxoQeS27tizWDZIAa+89Skev/IKz+92uHnOjlQCyuiQ3R4x9oiyptQVKs1IA8XVPZrLR4hTe/X+a6/x6NXXSCfTpKIs2FxcZlLmMJw0fPOJpXtq1Mg81iQBVgliTKzXG4wtcLOjPIFb3mfvvP1+z/F4QCqJTRmOvbvbM08TiyYbTG42G/aH/Ue6gMVizdC1lM3i4wf+bntHVW9Yrxc0TcP7736dhKLtehKaqlpQFg0iOYKbmLs7kAZjK+yiRmnJ4bjPydo4crfdcXF2ll2gDy1FUbNYnSMFlNWSYRqRi4KyrIGIcwGlDKvzK8qy4u7umv7Q5R7+POPuJowtkLbGxYgSuWWbSZcBbQQ6ZTLl1LXc3tzy8NEjFkvD7/2RH+PJ++9zd8xa/avNmicvbpne+Q1eOdxQFCXnZxc0yxXrWtOc3yOaghQ867ML1lf3s0Y9JbzzFGUJKWVlThIZoJIyCyXIGoVxHD4aa2ZtQUoxn8naIIvseJ1Sou97xrGnsIr6/n2KomQae/wUmd3M5BwNGfOPwXG2WfP8+XNsURIjIATbu9uPH/hp9tSNYLVeM/QnzXtZ41LBsRuQAqbhiB/2nD98g7KU+Hlk6nckFFWzoj3uMbZEhMTZeklZ1oQw88rjx8iTNGjyHpAYpSnLgrquefrsA1LKxMNpVsQUaRYrpNJUVYNShr7rOXYdx3Ggnz2CTLAcQyLOGaypjMYully9/hbL9ZrJebQ2fOH3/RAyRX7m//P/Zn93w2WlWLz6kOvDkaOCIBINYKYjzcNXiEVJSo71xT0+9X3fx3K1yt07XXA4HDF6RkuBoGCchpNPXbYhH/uWaU7YssSY4qOMfBwzMfXD50kpuLvbEkLCGpuNHmzWwA3tDlM23L+6xziOeDdTlhUkRYiO5XJF13U8+eAdLi/vs1wsP37gS6vRSqC15vr5bR7mJyRKRtpxghSoNIy7F3TLK1zwVGWFKTekOBOmljBPUFikVCwXG6qq5NnzFruygCN5R6JgmrLsp24a+v54sgZVWSUrRPbMFYLN+iwLKoLjK1/5MvMcub27o5+zV102TBDEGPB+BjdiFNiyytlviFRliVaSH/o3/iSf//7fwzu/+iu8eOc3IUSmfqQfM5FhWRWcnW8ozi5YnF+wuLjg3uNXadZnpJQomhqjC4qyoj9sGYaRKHMdXRQ1MWYp88E5ptlTVgX77S2LdTY40toy9B1d15JSjff61OnMIlKtJdoUdP2ALhfIONO2LbaoccNA6Idckvo56xb7ARDMLjAOh48feJEc3k+MQ8fhcKBZnoOU3NzeIpSmLpZMcoV59H3ZI+50x7l+ZrlaMBx7ksjuTUVRIJUFIbi4uMRaQ3fcZRcNHIVV2VCYSHs85LNUgY/ZzTELNfOoMunziLDVasOT997j9uYaF046Nx8odKI2Ci0y5r0/tHg3n6ZJRIRQJ+WuoHz1TVRR87nf/8OURcnh+jlP3v4K43FP2SxZXpxz+cobVKs1VZXtTcaxYxomqrpGaY2REqXusd/vgMA0TZm2ZbIL2DS7k/AyUi/WeAdTGIFEVTfUIhsv7fd5fFuMHqWz1dw49EzjRAqBkBKqkAR/2i2kRGlNYcusUCoL6qrgcNjTdcePH/jFcs08z9zd3iJF7gRpbSmMZLVaEROIOKFMcVKeSrSyCJOx+cM0sFrdJwqRHS7HkeDzDjJNIcuybEkaB5JULFdnHPb7rJnXlhAyt72usovWOE1IoU5vsubB/Yf8w7//d2n7AX2SNkuZa+QoFF4I2ih4VC84O7+HloKuG7BFxd1ux7O7A4uq4NUHF1xcXAKJxWbD4uoBtzfXFLZAasVic4YpSobpww+7RDpP8C4HeZ6BlGfoKcl6vUZJye3t7mRHJvP8mhDYthOH3vPwvEbLxGF3iw+5Ddw0Kw6HAynFE7EkEiJUpeGw65EEymZJ1x6xVhOTxBaZw18UltvhBSEl3NTllvRL1ku7c5f3H6IIXF+/yNYbtx/w4snXMdbm5KO0lFZRykBpc/my3d6glKA97AHJPGwJ44FCR9aLAlsWeVeYc3mmpMBaTV3nwT9329vTQKKCxWJJXVfMLg86msaeFD2j82y3N3zl1/4p777ztY/YNtYUWFtQVRWL5ZqqWmHrJeGkfbu7eZ6Pg+QpNDRWUDc1m805Ugpub6/Zbres1mvOL+4htDz5+OTAzvOMVJabTlCvr6jqRWYFlyXOzVRVifc+EypTpK7LDNggctNFKoyInDWZS5BHjMnTAIiWeZ6o6zobGnddxvwPe8bRERGElPBuwjuH8/ldpxRxfmKeO0ojcN0dy9pS229CLYs0LNYbnl6/zdXVI2xVk8I3BE3AOA3EkKiq6mRParDGcv3iCQKNKmqqqsDNE+32BVqKjIppwzgMmT0aE6KWuNNYDqUNXddSlhWHfR6sUxaaeRowOvefjSl5+52v5VluSiFObdoPx5IYW2KVPvWyHcNhz71XXkcbzeHuOcpYVpXl9VceYK3l+vpZ9ou3FmsL7l1ecdzf5tl1Iv/9rISJ9MNMX0pUmmmamv2xp26W2Y7tRIn2wXF2vuG4P9D3LUu9Yeg7gp+omiV6s2aeOgKKs8WaaR44Ho9ZM7hecTy2Jx9hR/ATi+Waaewz6bQosEiMKRjGPL8uq3KPIA26WrNYfBN2Z6Sc2RdFyXJzwTCOeDdx996v8eiT388wTCSyetWHQAye5XKFDzNu9oQYkWokAcYYqtqSUmCaR7o+l3mrRYNUkmk4sp9njsfjR96tuWkhWVYZ4dLaYMsaHSPPk89+rSlhtEYbS2kLtBT4FNBSMLuJwzhQiMjh7oYHb30GazSxPscYxeX9+0Di+voFQz9iYk/T3GOeA2VhaRYr5jkLF6ZpJPhASI6LMlEy0Lc+U7FPTt1D32bXqbGjqk/zX2PEec88z/TdkYt793BBIFSZ3b2PB8R+l5k404Q8HUeLxYK+z+Peur5HSM04zifPwALvZw7HHVVpmMeRYztQFAuIgWny2NU3UccLkfnzVVWfko8dTVVx9tr3oEyeptQPAykGtFrgoqQqK3a7F4CkKBcIKfBuwmh5mkGrEapksSzzluUya6UoDG6aWC7XWbe+PiMhsLYkJc98uKYfHdoWef5qVSNFNkZAptwzSNkFO5JHeHZDn7n8VhPmDi2yj01dWRarFUVR8uLFc4ZhRIURIwOTc2g107Yj680mO1ZOM8OYx6VHAimOhFBRn3oFyU35rBH6NLsnn6AhhDwm7OR8lX0EYBgdT+9a3ny4ycqZ2VNWJRdFTYzw5MUN59NAVTdUVUMMkd1uS13X1PWGYeiy0eQ00h13mKJBqIqyrGlvP2D280nw+Vuvlz4a/EzX5xmxIeXEqR0GnrzY5t6xd3T9fKL4ZjMBH+bcLvSeGCbG/ojSimPvOQyacfT03ZHd7kAIAaShXqxQAqKP1HVDszzDjQNdu2d2DqM1LkQWq3O0tmhTYcuSh49fRZz62UYK3DQyzhO7Y8v2sIMYqK1FasHDNz6RrVfchNQWpQ3Pnj5h6LNHbb08x6xfxdbZpyeEcJrDU5z8bvN7dG6mqGrGOdD2I/M0E0LMLp8JQoQPPd9ijKfxJc1J2ZO1+VYl7m9Kdttt5uLZkohCnwZCNAaun7zLfrdDK5U5dlJijEXiKXRiv99mdyyfKIs8Gw8RaV3CC3ua1P0x7/j2uM93gyrZtwMpGepSZVIDWX18s+2oC2gWS5aLfM7N44gq8ix1oYrcix4DQpUkmbtIRWFxfmIYPItFzeE4ooyhKC273R2FMR/ZhcQE1eqKrm/xw4gxBRfnZ/zBH/1xdts73vnKV4g+cLFa8f7tNVZKHp+fZXULcPHq69Sbe1T1khQ9fdcSgmO32+cdhYgyoFWeJFEUFqWz64T34aNhw9M8cjjsWa82oAoObU+KLZf3NpTVIkOywRFCIoSsbfcu07ZjgOADbddT1zVNXRBcHjl26AYQMIpECp5pDlTr+xhbsN3dsFyuKct7TH3LNI1MLqFNRRIlQoIgsCizH48QCmOKD92eP94dn31dNPVyw+VmwWrZUFhDs9iw3d5xd/2Mi7MVq8WSFBzaKKZxQEhFVS6yPmy1oShqpAhcbCqkLkgYjBZoJbm8vMQayzQ7pMpGxx+8/3UOxwPGFhQ2s1Odn2iPhzwsmMT5+Tmf+exn+JN/5s/x6PEjDu0RFzxSKRZ1TSKbHf9rP/mT/L4//Efp50TXz1R1zXK5ZLfN2r4YArd3d3k2fR84Hg8cdnfI5JnH/tQUyirgsixYLBY450h+xOjsDLZcraibEmNlnhAtMt2q644oreE0onwcB7bbW+5uX/Dkq/8UazKHvttvGY4HDvs89cMYQ7OoKcqSsmryUKehZbffc+wmZg9KaRLZum12MwiFsYb7D18BuyIJ9fHv+ON+T1012W8+BJIfkUWBFJKb6+eI6PnEpz7LsH2KXL6Zz/zuSBICYxX9GNjutrTtEecmNmf3gIjR+UV+OD9+GvMclZQSMURef/2tk5NlYOgdMQasLSjLEiEU1uSLIaXA41de5w/8yI/y3te/jtGS+/cuuL65ox0Sv/eLn+JHfuKPokxBPwwUNnPPnz/5gISkaUqssdR1lnvvWkeceh5cnWPLBp0itqhoDweW69VH9XWMDghcXV0iRDZzHoae3KDKXPrs1i6p69NMWp1YrpZoYwjzgPM3uNkRyPP3Ptg7zlc196qKokykmCnsU9+ddHETzXKF1iajnGV5urg6vvzOMx5dnbMoJK2ruB4En334TUC2+2PL5uw+4zhQFNVHV3BhDfcfPobosWWFrzcgJCF4xmEAFPOcdfNSWVZnD5Ep16RCavb7Q55DqyGlyG57i/ORiKOpc3PHuTGTDduO4B3W6pNPXR4D2h33jO2R0SW+7wf/ANM8IqaB+699ip/5+z/NZlHyQz/2I5mYqbOEurR5+O7heGS1PmO12nDY32KtpSwKNouAXFycOl3ZVx8yldmWJUppzs7OGMcRrTXD0CPQSCWAzHqNMeFOUidbFFRlQwjpNImzxZgCWVSYq88wzTEPbiBytmxY1CVaKcZhYBw7ghsJIc/kTSLX+0VhGccBN3u+9hu/ClKQ9AZ0ST+2hJRY2TILWD5u4MdpPqFRJp999Yq6Kum6luX6Ik9UDA5dn1E3DTF42m5gc/4gZ/PTjNQLlCkppcgwYtI0yyXDMDE5xwOjiTHgZpfNleKMShatCrp2QGnD7e0Nq/WGumqyC0dVZZxAKBaLkqIw/Os/+Uc5HI7cf/Aqn/rc57FW53luJyfOssqt02fvfJDdMaWkPeQO1jgHbD+wWdYcjkfm2SNldsEkBZZNVgsbk+fLBu8Zh55xnLCFxdgaowXTOJNn0E3UdXkSS+SACyG4urxkv7slRk9Zr5nmjmM3U1clC6Woas3x2HM43JCiw00TISmUzt6C1lZorWjqmtu7W64evU5dlyibZ+pdvxhZLpaUhfnI5ftjBb4fRvbHlgQUVU0ShqcfvI/SFjl6bFETQ74bpczjNmLMEyBE8LlG15ab7Q2isdR1tk1zDoxKXF7mOjqFmdIqmkKRMkaV62CjTzq4h2x3d9mrznm6ruVwOCBPThHO5Rl3WhvqQrN85VW883SHO8Q8I+oNkGVS4zRT1jVVvWR/OLBsKpwLPHnyAZf3HzH4SKVFtiWxlmHomH1Ps7j4aDJEVVmIM13w9L3HBs12nllUBaBoFgu8m+m6A8du4OL8HEFkmmeaxZIYA23XZksTbU/W7olnz16w294gRaIoS5bnDwguZBeSfqA9btGmODlrevrRUS8a1ssl0ziwaBZAxjU+9Pb/WIFfNIs8SbkomcaJs9WSF32RGajdAaMVZVGAPUcISd8es3V3t8NI8MZiyiUmdIhkP5IKNU2J0gaIDH3P7BJSZ3MhpTTTsWdo95mXVjYUVvLaq48JIbHb7ZjGgbZtkSpz0Xb7Y+52naRGJoo8pFdr3DyRIqwXi9OdJ0+c9eyc/ZFbp5ZYo1g0FUoqpmnIXDlbcH5+wW53x93dXR4YsMmDkRcxnRpAA1VRZFOomDgcc+Y/O0+SCiFT5sBvdxhrWS8brC2AFiPBucDzmzvu7m6QyWFtwXKdbU7naeLs7Az74eDm/sB6s0YpQQwzSmoOAxAERZHdsZ9tOwwvNz96aVavtaVrD9zdPMM5x2F/wBaWtj+SSBTVElVkqc+HGrAE7Pctw+R5etvy5XeeYsqaeXb85le+SkiCfhhP8+gM1y+ecGx7fBTsDgM+SGyzwVQbkCWzc/R9x3G/ZXv3guRH/JyPgKKo6Pse58ZT5t2AbjgcWt5//z2G2VNv7qFk5vDtdrtMFDUFh2PP8bBlHDqcm0/bv8bNM7fbLcPk8VHRNEvGsaPv2wzfhsg8O0yRjxGtTB4OIKEoS/IsRH0yflZcna2JIdAe9/lzSoLbXZ7Eaa1lmhztcUd/PCBSZL064/Err7NcNigp0EaxO7Yc2z7L0kymt9XNghQD7XFHdH2e5HG6ENt+ZPbfBGQrhCC6ibpZ0E8jJgjmceD87IIYQ37zOnvYGqNxbsbYAq0F290BWy149X5Gv8Zh4LVXX8ENHWM01IXKciGlsVVNVddsn10DR+wwnebZGebZoZWgqips0RBDNv4lfTi2c0br4jQxyyMlXG93LOsCY0vGcaQsM6I2DANKa6RdMqeE0IkU4YO3fx1dFJSvfeo0FrRgdxy5ushQ8fX1HeOYhxMobXDOU5YVRWE5P5O4sOBwaJHS5MFKTZlZsRH8PGXHCyUISEot2B8GvIDt9o7jYZ95eCFwee8KYzRlVWX5dhjRSjOPI5vzc9xY8t6zO0iJs80aba559uw55y5RWI1UmbC5LiRSpJcGXqT08id8Z/3uXC8HdL+zfteu7wT+23R9J/Dfpus7gf82Xd8J/Lfp+k7gv03X/xcCuAtXj1yafgAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_titled_image((im3,'A puppy'), figsize=(2,2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Show all images `ims` as subplots with `rows` using `titles`. `suptitle` provides a way to create a figure title for all images. If you use `suptitle`, `constrained_layout` is used unless you set `constrained_layout` to `False`. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@delegates(subplots)\n",
    "def show_images(ims, nrows=1, ncols=None, titles=None, **kwargs):\n",
    "    \"Show all images `ims` as subplots with `rows` using `titles`.\"\n",
    "    if ncols is None: ncols = int(math.ceil(len(ims)/nrows))\n",
    "    if titles is None: titles = [None]*len(ims)\n",
    "    axs = subplots(nrows, ncols, **kwargs)[1].flat\n",
    "    for im,t,ax in zip(ims, titles, axs): show_image(im, ax=ax, title=t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x216 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_images((im,im3),titles=('number','puppy'),suptitle='Number Puppy',  imsize=3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`ArrayImage`, `ArrayImageBW` and `ArrayMask` are subclasses of `ndarray` that know how to show themselves."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayBase(ndarray):\n",
    "    \"An `ndarray` that can modify casting behavior\"\n",
    "    @classmethod\n",
    "    def _before_cast(cls, x): return x if isinstance(x,ndarray) else array(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayImageBase(ArrayBase):\n",
    "    \"Base class for arrays representing images\"\n",
    "    _show_args = {'cmap':'viridis'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        return show_image(self, ctx=ctx, **{**self._show_args, **kwargs})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayImage(ArrayImageBase):\n",
    "    \"An array representing an image\"\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayImageBW(ArrayImage):\n",
    "    \"An array representing an image\"\n",
    "    _show_args = {'cmap':'Greys'}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayMask(ArrayImageBase):\n",
    "    \"An array representing an image mask\"\n",
    "    _show_args = {'alpha':0.5, 'cmap':'tab20', 'interpolation':'nearest'}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "im = Image.open(TEST_IMAGE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "im_t = cast(im, ArrayImage)\n",
    "test_eq(type(im_t), ArrayImage)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = im_t.show(figsize=(2,2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_fig_exists(ax)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Basics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def __array_eq__(self:Tensor,b):\n",
    "    return torch.equal(self,b) if self.dim() else self==b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _array2tensor(x):\n",
    "    if x.dtype==np.uint16: x = x.astype(np.float32)\n",
    "    # windows default numpy int dytpe is int32, while torch tensor default int dtype is int64\n",
    "    # https://github.com/numpy/numpy/issues/9464\n",
    "    if sys.platform == \"win32\":\n",
    "        if x.dtype==np.int: x = x.astype(np.int64)\n",
    "    return torch.from_numpy(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@use_kwargs_dict(dtype=None, device=None, requires_grad=False, pin_memory=False)\n",
    "def tensor(x, *rest, **kwargs):\n",
    "    \"Like `torch.as_tensor`, but handle lists too, and can pass multiple vector elements directly.\"\n",
    "    if len(rest): x = (x,)+rest\n",
    "    # There was a Pytorch bug in dataloader using num_workers>0. Haven't confirmed if fixed\n",
    "    # if isinstance(x, (tuple,list)) and len(x)==0: return tensor(0)\n",
    "    res = (x if isinstance(x, Tensor)\n",
    "           else torch.tensor(x, **kwargs) if isinstance(x, (tuple,list))\n",
    "           else _array2tensor(x) if isinstance(x, ndarray)\n",
    "           else as_tensor(x.values, **kwargs) if isinstance(x, (pd.Series, pd.DataFrame))\n",
    "#            else as_tensor(array(x, **kwargs)) if hasattr(x, '__array__') or is_iter(x)\n",
    "           else _array2tensor(array(x), **kwargs))\n",
    "    if res.dtype is torch.float64: return res.float()\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(tensor(torch.tensor([1,2,3])), torch.tensor([1,2,3]))\n",
    "test_eq(tensor(array([1,2,3])), torch.tensor([1,2,3]))\n",
    "test_eq(tensor(1,2,3), torch.tensor([1,2,3]))\n",
    "test_eq_type(tensor(1.0), torch.tensor(1.0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```set_seed``` is useful for reproducibility between runs. It is important to remember that certain classes such as ```Dataloaders``` have internal random number generators that is not effected by this function, so this must be run before such objects are created in order to guarantee reproducibility. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def set_seed(s, reproducible=False):\n",
    "    \"Set random seed for `random`, `torch`, and `numpy` (where available)\"\n",
    "    try: torch.manual_seed(s)\n",
    "    except NameError: pass\n",
    "    try: torch.cuda.manual_seed_all(s)\n",
    "    except NameError: pass\n",
    "    try: np.random.seed(s%(2**32-1))\n",
    "    except NameError: pass\n",
    "    random.seed(s)\n",
    "    if reproducible:\n",
    "        torch.backends.cudnn.deterministic = True\n",
    "        torch.backends.cudnn.benchmark = False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here is an example of how ```set_seed``` can be used to reset the state of random number generators."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a's: 0.154 0.498 0.071\n",
      "b's: 0.154 0.498 0.071\n"
     ]
    }
   ],
   "source": [
    "set_seed(2*33)\n",
    "a1 = np.random.random()\n",
    "a2 = torch.rand(())\n",
    "a3 = random.random()\n",
    "set_seed(2*33)\n",
    "b1 = np.random.random()\n",
    "b2 = torch.rand(())\n",
    "b3 = random.random()\n",
    "print('a\\'s: {0:3.3f} {1:3.3f} {2:3.3f}'.format(a1,a2,a3))\n",
    "print('b\\'s: {0:3.3f} {1:3.3f} {2:3.3f}'.format(b1,b2,a3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(a1,b1)\n",
    "test_eq(a2,b2)\n",
    "test_eq(a3,b3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```get_random_states``` and ```set_random_states``` are useful for storing a state so you can go back to it later. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def get_random_states():\n",
    "    \"Gets states for `random`, `torch`, and `numpy` random number generators\"\n",
    "    return {'random_state':random.getstate(),\n",
    "            'numpy_state':np.random.get_state(),\n",
    "            'torch_state':torch.get_rng_state(),\n",
    "            'torch_cuda_state':torch.cuda.get_rng_state_all(),\n",
    "            'torch_deterministic':torch.backends.cudnn.deterministic,\n",
    "            'torch_benchmark':torch.backends.cudnn.benchmark}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def set_random_states(random_state,numpy_state,torch_state,torch_cuda_state,torch_deterministic,torch_benchmark):\n",
    "    \"Set states for `random`, `torch`, and `numpy` random number generators\"\n",
    "    random.setstate(random_state)\n",
    "    np.random.set_state(numpy_state)\n",
    "    torch.set_rng_state(torch_state)\n",
    "    torch.cuda.set_rng_state_all(torch_cuda_state)\n",
    "    torch.backends.cudnn.deterministic=torch_deterministic\n",
    "    torch.backends.cudnn.benchmark=torch_benchmark"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below notice that the old values and rewinded values are the same because we were able to return to the previous state. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "olds:    0.435 0.134 0.023\n",
      "news:    0.246 0.363 0.227\n",
      "rewinds: 0.435 0.134 0.023\n"
     ]
    }
   ],
   "source": [
    "old_states = get_random_states()\n",
    "olds = (random.random(),np.random.random(),torch.rand(()))\n",
    "news = (random.random(),np.random.random(),torch.rand(()))\n",
    "set_random_states(**old_states)\n",
    "rewinds = (random.random(),np.random.random(),torch.rand(()))\n",
    "\n",
    "print('olds:    {0:3.3f} {1:3.3f} {2:3.3f}'.format(*olds))\n",
    "print('news:    {0:3.3f} {1:3.3f} {2:3.3f}'.format(*news))\n",
    "print('rewinds: {0:3.3f} {1:3.3f} {2:3.3f}'.format(*rewinds))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_ne(olds,news)\n",
    "test_eq(olds,rewinds)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In ```no_random``` we combine the ideas of rewinding state with ```get_random_states``` and ```set_random_states``` with the ability to ```set_seed``` and create a context manager that can allow us to control randomness in a portion of our code. \n",
    "\n",
    "Note: Similar to ```torch.random.fork_rng```, but also with ```numpy``` and ```random```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@contextmanager\n",
    "def no_random(seed=42,reproducible=True):\n",
    "    \"Stores and retrieves state of random number generators. Sets random seed for `random`, `torch`, and `numpy`.\"\n",
    "    states = get_random_states()\n",
    "    set_seed(seed,reproducible=reproducible)\n",
    "    try:\n",
    "        yield #we are managing global variables\n",
    "    finally:\n",
    "        set_random_states(**states)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here are some examples on how we can use ```no_random``` to control the randomness within a block of code.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "olds:    0.246 0.363 0.227\n",
      "new1:    0.639 0.375 0.882\n",
      "new2:    0.639 0.375 0.882\n",
      "seeded1: 0.146 0.543 0.112\n",
      "seeded2: 0.146 0.543 0.112\n",
      "rewinds: 0.246 0.363 0.227\n"
     ]
    }
   ],
   "source": [
    "states=get_random_states()\n",
    "olds = (random.random(),np.random.random(),torch.rand(()))\n",
    "set_random_states(**states) #rewinding above random calls\n",
    "\n",
    "with no_random():\n",
    "    new1 = (random.random(),np.random.random(),torch.rand(()))\n",
    "with no_random():\n",
    "    new2 = (random.random(),np.random.random(),torch.rand(()))\n",
    "with no_random(seed=100):\n",
    "    seeded1 = (random.random(),np.random.random(),torch.rand(()))\n",
    "with no_random(seed=100):\n",
    "    seeded2 = (random.random(),np.random.random(),torch.rand(()))\n",
    "        \n",
    "rewinds = (random.random(),np.random.random(),torch.rand(()))\n",
    "\n",
    "print('olds:    {0:3.3f} {1:3.3f} {2:3.3f}'.format(*olds))\n",
    "print('new1:    {0:3.3f} {1:3.3f} {2:3.3f}'.format(*new1))\n",
    "print('new2:    {0:3.3f} {1:3.3f} {2:3.3f}'.format(*new2))\n",
    "print('seeded1: {0:3.3f} {1:3.3f} {2:3.3f}'.format(*seeded1))\n",
    "print('seeded2: {0:3.3f} {1:3.3f} {2:3.3f}'.format(*seeded2))\n",
    "print('rewinds: {0:3.3f} {1:3.3f} {2:3.3f}'.format(*rewinds))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that olds, and rewinds are alos both equal to each other. From this  we can see that everything in the ```with``` blocks did not update the state outside of the block. Inside of the block, the state is reset for any particular seed, so for the same seed you should get the same random number generator results.  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note: It is important to remember that classes like ``` Dataloader``` have internal random number generators, and ```no_random``` will have no effect on those random number generators."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_ne(olds,new1)\n",
    "test_eq(new1,new2)\n",
    "test_ne(new1,seeded1)\n",
    "test_eq(seeded1,seeded2)\n",
    "test_eq(olds,rewinds)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def unsqueeze(x, dim=-1, n=1):\n",
    "    \"Same as `torch.unsqueeze` but can add `n` dims\"\n",
    "    for _ in range(n): x = x.unsqueeze(dim)\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([1])\n",
    "t2 = unsqueeze(t, n=2)\n",
    "test_eq(t2,t[:,None,None])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def unsqueeze_(x, dim=-1, n=1):\n",
    "    \"Same as `torch.unsqueeze_` but can add `n` dims\"\n",
    "    for _ in range(n): x.unsqueeze_(dim)\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([1])\n",
    "unsqueeze_(t, n=2)\n",
    "test_eq(t, tensor([1]).view(1,1,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _fa_rebuild_tensor (cls, *args, **kwargs): return cls(torch._utils._rebuild_tensor_v2(*args, **kwargs))\n",
    "def _fa_rebuild_qtensor(cls, *args, **kwargs): return cls(torch._utils._rebuild_qtensor  (*args, **kwargs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def apply(func, x, *args, **kwargs):\n",
    "    \"Apply `func` recursively to `x`, passing on args\"\n",
    "    if is_listy(x): return type(x)([apply(func, o, *args, **kwargs) for o in x])\n",
    "    if isinstance(x,dict):  return {k: apply(func, v, *args, **kwargs) for k,v in x.items()}\n",
    "    res = func(x, *args, **kwargs)\n",
    "    return res if x is None else retain_type(res, x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def maybe_gather(x, axis=0):\n",
    "    \"Gather copies of `x` on `axis` (if training is distributed)\"\n",
    "    if num_distrib()<=1: return x\n",
    "    ndim = x.ndim\n",
    "    res = [x.new_zeros(*x.shape if ndim > 0 else (1,)) for _ in range(num_distrib())]\n",
    "    torch.distributed.all_gather(res, x.contiguous() if ndim > 0 else x[None])\n",
    "    return torch.cat(res, dim=axis) if ndim > 0 else torch.cat(res, dim=axis).mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_detach(b, cpu=True, gather=True):\n",
    "    \"Recursively detach lists of tensors in `b `; put them on the CPU if `cpu=True`.\"\n",
    "    def _inner(x, cpu=True, gather=True):\n",
    "        if not isinstance(x,Tensor): return x\n",
    "        x = x.detach()\n",
    "        if gather: x = maybe_gather(x)\n",
    "        return x.cpu() if cpu else x\n",
    "    return apply(_inner, b, cpu=cpu, gather=gather)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`gather` only applies during distributed training and the result tensor will be the one gathered across processes if `gather=True` (as a result, the batch size will be multiplied by the number of processes)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_half(b):\n",
    "    \"Recursively map lists of tensors in `b ` to FP16.\"\n",
    "    return apply(lambda x: x.half() if torch.is_floating_point(x) else x, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_float(b):\n",
    "    \"Recursively map lists of int tensors in `b ` to float.\"\n",
    "    return apply(lambda x: x.float() if torch.is_floating_point(x) else x, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "# None: True if available; True: error if not available; False: use CPU\n",
    "defaults.use_cuda = None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def default_device(use_cuda=-1):\n",
    "    \"Return or set default device; `use_cuda`: None - CUDA if available; True - error if not available; False - CPU\"\n",
    "    if use_cuda != -1: defaults.use_cuda=use_cuda\n",
    "    use = defaults.use_cuda or (torch.cuda.is_available() and defaults.use_cuda is None)\n",
    "    assert torch.cuda.is_available() or not use\n",
    "    return torch.device(torch.cuda.current_device()) if use else torch.device('cpu')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# cuda\n",
    "if torch.cuda.is_available():\n",
    "    _td = torch.device(torch.cuda.current_device())\n",
    "    test_eq(default_device(None), _td)\n",
    "    test_eq(default_device(True), _td)\n",
    "else:\n",
    "    test_eq(default_device(False), torch.device('cpu'))\n",
    "default_device(None);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_device(b, device=None, non_blocking=False):\n",
    "    \"Recursively put `b` on `device`.\"\n",
    "    if defaults.use_cuda==False: device='cpu'\n",
    "    elif device is None: device=default_device()\n",
    "    def _inner(o):\n",
    "        if isinstance(o,Tensor): return o.to(device, non_blocking=non_blocking)\n",
    "#         if hasattr(o, \"to_device\"): return o.to_device(device)\n",
    "        return o\n",
    "    return apply(_inner, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = to_device((3,(tensor(3),tensor(2))))\n",
    "t1,(t2,t3) = t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# cuda\n",
    "if torch.cuda.is_available():\n",
    "    test_eq_type(t,(3,(tensor(3).cuda(),tensor(2).cuda())))\n",
    "    test_eq(t2.type(), \"torch.cuda.LongTensor\")\n",
    "    test_eq(t3.type(), \"torch.cuda.LongTensor\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_cpu(b):\n",
    "    \"Recursively map lists of tensors in `b ` to the cpu.\"\n",
    "    return to_device(b,'cpu')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t3 = to_cpu(t3)\n",
    "test_eq(t3.type(), \"torch.LongTensor\")\n",
    "test_eq(t3, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_np(x):\n",
    "    \"Convert a tensor to a numpy array.\"\n",
    "    return apply(lambda o: o.data.cpu().numpy(), x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t3 = to_np(t3)\n",
    "test_eq(type(t3), np.ndarray)\n",
    "test_eq(t3, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_concat(xs, dim=0):\n",
    "    \"Concat the element in `xs` (recursively if they are tuples/lists of tensors)\"\n",
    "    if not xs: return xs\n",
    "    if is_listy(xs[0]): return type(xs[0])([to_concat([x[i] for x in xs], dim=dim) for i in range_of(xs[0])])\n",
    "    if isinstance(xs[0],dict):  return {k: to_concat([x[k] for x in xs], dim=dim) for k in xs[0].keys()}\n",
    "    #We may receive xs that are not concatenable (inputs of a text classifier for instance),\n",
    "    #   in this case we return a big list\n",
    "    try:    return retain_type(torch.cat(xs, dim=dim), xs[0])\n",
    "    except: return sum([L(retain_type(o_.index_select(dim, tensor(i)).squeeze(dim), xs[0])\n",
    "                          for i in range_of(o_)) for o_ in xs], L())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(to_concat([tensor([1,2]), tensor([3,4])]), tensor([1,2,3,4]))\n",
    "test_eq(to_concat([tensor([[1,2]]), tensor([[3,4]])], dim=1), tensor([[1,2,3,4]]))\n",
    "test_eq_type(to_concat([(tensor([1,2]), tensor([3,4])), (tensor([3,4]), tensor([5,6]))]), (tensor([1,2,3,4]), tensor([3,4,5,6])))\n",
    "test_eq_type(to_concat([[tensor([1,2]), tensor([3,4])], [tensor([3,4]), tensor([5,6])]]), [tensor([1,2,3,4]), tensor([3,4,5,6])])\n",
    "test_eq_type(to_concat([(tensor([1,2]),), (tensor([3,4]),)]), (tensor([1,2,3,4]),))\n",
    "\n",
    "test_eq(to_concat([tensor([[1,2]]), tensor([[3,4], [5,6]])], dim=1), [tensor([1]),tensor([3, 5]),tensor([4, 6])])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(type(to_concat([dict(foo=tensor([1,2]), bar=tensor(3,4))])), dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Tensor subtypes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def set_meta(self:Tensor, x, as_copy=False):\n",
    "    \"Set all metadata in `__dict__`\"\n",
    "    if not hasattr(x,'__dict__'): return\n",
    "    # XXX: change to `deepcopy` once PyTorch 1.7.1 is out, and check nb 23 segmentation fit works\n",
    "    self.__dict__ = copy(x.__dict__) if as_copy else x.__dict__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "if not hasattr(torch,'as_subclass'): torch.as_subclass = torch.Tensor.as_subclass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def as_subclass(self:Tensor, typ):\n",
    "    \"Cast to `typ` and include `__dict__` and meta\"\n",
    "    return retain_meta(self, torch.as_subclass(self, typ))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`Tensor.set_meta` and `Tensor.as_subclass` work together to maintain `__dict__` after casting."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class _T(Tensor): pass\n",
    "t = tensor(1.).requires_grad_()\n",
    "t.img_size = 1\n",
    "t2 = t.as_subclass(_T)\n",
    "test_eq(t.img_size, t2.img_size)\n",
    "test_eq(t2.img_size, 1)\n",
    "assert(t2.requires_grad_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _torch_handled(args, opt, func):\n",
    "    if func not in opt: return False\n",
    "    for oks in opt[func]:\n",
    "        if all(isinstance(arg,ok) for arg,ok in zip(args,oks) if ok): return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "# from https://github.com/pytorch/pytorch/blob/13c975684a220ec096216ec6468ccd0dc90ff50a/torch/_tensor.py#L34\n",
    "def _rebuild_from_type(func, type, args, dict):\n",
    "    ret = func(*args).as_subclass(type)\n",
    "    ret.__dict__ = dict\n",
    "    return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorBase(Tensor):\n",
    "    \"A `Tensor` which support subclass pickling, and maintains metadata when casting or after methods\"\n",
    "    debug,_opt = False,defaultdict(list)\n",
    "    def __new__(cls, x, **kwargs):\n",
    "        res = cast(tensor(x), cls)\n",
    "        for k,v in kwargs.items(): setattr(res, k, v)\n",
    "        return res\n",
    "\n",
    "    @classmethod\n",
    "    def _before_cast(cls, x): return tensor(x)\n",
    "    def __repr__(self): return re.sub('tensor', self.__class__.__name__, super().__repr__())\n",
    "\n",
    "    def __reduce_ex__(self,proto):\n",
    "        torch.utils.hooks.warn_if_has_hooks(self)\n",
    "        args = (self.storage(), self.storage_offset(), tuple(self.size()), self.stride())\n",
    "        if self.is_quantized: args = args + (self.q_scale(), self.q_zero_point())\n",
    "        args = args + (self.requires_grad, OrderedDict())\n",
    "        f = torch._utils._rebuild_qtensor if self.is_quantized else  torch._utils._rebuild_tensor_v2\n",
    "        return (_rebuild_from_type, (f, type(self), args, self.__dict__))\n",
    "\n",
    "    @classmethod\n",
    "    def register_func(cls, func, *oks): cls._opt[func].append(oks)\n",
    "\n",
    "    def __torch_function__(self, func, types, args=(), kwargs=None):\n",
    "        if self.debug and func.__name__ not in ('__str__','__repr__'): print(func, types, args, kwargs)\n",
    "        convert=False\n",
    "        if _torch_handled(args, self._opt, func): convert,types = type(self),(torch.Tensor,)\n",
    "        res = super().__torch_function__(func, types, args=args, kwargs=kwargs)\n",
    "        if convert: res = convert(res)\n",
    "        if isinstance(res, TensorBase): res.set_meta(self, as_copy=True)\n",
    "        return res\n",
    "\n",
    "    def new_tensor(self, size, dtype=None, device=None, requires_grad=False):\n",
    "        cls = type(self)\n",
    "        return self.as_subclass(Tensor).new_tensor(size, dtype=dtype, device=device, requires_grad=requires_grad).as_subclass(cls)\n",
    "\n",
    "    def new_ones(self, data, dtype=None, device=None, requires_grad=False):\n",
    "        cls = type(self)\n",
    "        return self.as_subclass(Tensor).new_ones(data, dtype=dtype, device=device, requires_grad=requires_grad).as_subclass(cls)\n",
    "\n",
    "    def new(self, x=None):\n",
    "        cls = type(self)\n",
    "        res = self.as_subclass(Tensor).new() if x is None else self.as_subclass(Tensor).new(x)\n",
    "        return res.as_subclass(cls)\n",
    "    \n",
    "    def requires_grad_(self, requires_grad=True):\n",
    "        # Workaround https://github.com/pytorch/pytorch/issues/50219\n",
    "        self.requires_grad = requires_grad\n",
    "        return self"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`TensorBase` hooks into `__torch_function__` to ensure metadata is not lost. To see all functions being called, set `debug`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<method 'add' of 'torch._C._TensorBase' objects> (<class '__main__.TensorBase'>,) (TensorBase(1), 1) None\n",
      "<function Tensor.__rdiv__ at 0x7f43a09b9c10> (<class '__main__.TensorBase'>,) (TensorBase(2), 1) {}\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "TensorBase(0.5000)"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = TensorBase(1)\n",
    "a.debug=True\n",
    "1/(a+1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "_TImage2([2.])"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class _TImage(TensorBase): pass\n",
    "class _TImage2(_TImage): pass\n",
    "t1 = _TImage([1.])\n",
    "t2 = _TImage2([1.])\n",
    "t2+t1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class _T(TensorBase): pass\n",
    "\n",
    "t = _T(range(5))\n",
    "test_eq(t[0], 0)\n",
    "test_eq_type(t+1, _T(range(1,6)))\n",
    "test_eq(repr(t), '_T([0, 1, 2, 3, 4])')\n",
    "test_eq_type(t[_T([False,False,True,True,True])], _T([2,3,4]))\n",
    "test_eq_type(t[_T([2,3,4])], _T([2,3,4]))\n",
    "test_eq(type(pickle.loads(pickle.dumps(t))), _T)\n",
    "test_eq_type(t.new_ones(1), _T([1]))\n",
    "test_eq_type(t.new_tensor([1.,2.]), _T([1,2]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([1,2,3])\n",
    "m = TensorBase([False,True,True])\n",
    "test_eq(t[m], tensor([2,3]))\n",
    "t = tensor([[1,2,3],[1,2,3]])\n",
    "m = cast(tensor([[False,True,True],\n",
    "                 [False,True,True]]), TensorBase)\n",
    "test_eq(t[m], tensor([2,3,2,3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([[1,2,3],[1,2,3]])\n",
    "t.img_size = 1\n",
    "t2 = cast(t, TensorBase)\n",
    "test_eq(t2.img_size, t.img_size)\n",
    "x = retain_type(tensor([4,5,6]), t2)\n",
    "test_eq(x.img_size, t.img_size)\n",
    "t3 = TensorBase([[1,2,3],[1,2,3]], img_size=1)\n",
    "test_eq(t3.img_size, t.img_size)\n",
    "t4 = t2+1\n",
    "t4.img_size = 2\n",
    "test_eq(t2.img_size, 1)\n",
    "test_eq(t4.img_size, 2)\n",
    "# this will fail with `Tensor` but works with `TensorBase`\n",
    "test_eq(pickle.loads(pickle.dumps(t2)).img_size, t2.img_size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "# test of https://github.com/pytorch/pytorch/issues/47186\n",
    "class _T(TensorBase): ...\n",
    "t = _T([1.])\n",
    "test_eq_type(t.new([1,2]), _T([1.,2.]))\n",
    "test_eq_type(t.new(), _T([]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "# test of https://github.com/pytorch/pytorch/issues/50219\n",
    "x = TensorBase(torch.rand(4,3,16,16))\n",
    "with torch.no_grad():\n",
    "    y = x.requires_grad_()\n",
    "    assert y.requires_grad and x.requires_grad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorImageBase(TensorBase):\n",
    "    _show_args = ArrayImageBase._show_args\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        return show_image(self, ctx=ctx, **{**self._show_args, **kwargs})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorImage(TensorImageBase): pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorImageBW(TensorImage): _show_args = ArrayImageBW._show_args"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorMask(TensorImageBase):\n",
    "    _show_args = ArrayMask._show_args\n",
    "\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        codes = getattr(self, 'codes', None)\n",
    "        if codes is not None: kwargs = merge({'vmin': 0, 'vmax': len(codes)}, kwargs)\n",
    "        return super().show(ctx=ctx, **kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "for o in Tensor.__getitem__, Tensor.__ne__,Tensor.__eq__,Tensor.add,Tensor.sub,Tensor.mul,Tensor.div,Tensor.__rsub__,Tensor.__radd__,Tensor.matmul,Tensor.bmm:\n",
    "    TensorBase.register_func(o, TensorMask, TensorImageBase)\n",
    "    TensorBase.register_func(o, TensorImageBase, TensorMask)\n",
    "\n",
    "TensorMask.register_func(torch.einsum, str, TensorImageBase, TensorMask)\n",
    "TensorMask.register_func(torch.einsum, str, TensorMask, TensorImageBase)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "im = Image.open(TEST_IMAGE)\n",
    "im_t = cast(array(im), TensorImage)\n",
    "test_eq(type(im_t), TensorImage)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAH4AAABZCAYAAAD4ipAGAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAABN20lEQVR4nO392Y+uWXbeB/72+E7fFBEnIs6Qc40sFlkkJVKUSJqUadKWLRke0AakBtx3gv+Pvuqb/jcafdFo9IAWWm5rJC1ZIkWWSJFVZFVlVg5niohvfOc99cX+MtltQEkg68KAq95CAlknAwfxfevde631rOd5lkgp8ZPnx++R/0v/Aj95/pd5fhL4H9PnJ4H/MX1+Evgf0+cngf8xfX4S+B/TR3/ef/zn/+xfp2k6MbR7mtUj9qcBJWFZGd565z3uH14zDANSSBbLNVoJnA+cTkfcNGJsTVmWXFysKMqCvhv54z/+I/aHLdZalDC8//6f80/+8f+H97/3PaSQFGWDUYpFXfPk9pb/8u/9b/nWL/wiL198whwl7771jMuLC4QQnE4HZjeilKEsSwBSioQQ6fsBpSR93yNSoFluKEvLYtFgbcnLly8hSSCyfXhJTIK6tNSLC5arJVorhJDs91vKssK5GRD0o6cuLP35cxtrGMeRh4c7yrKhLCx13XB//4qrq2vatgMk+/2Bi4sL6rpguVoQQmC33XE4HrC2QAow2vLRJx/R1EuOxx2Xl48YhoEkFFJqju0R72aaZkFdL0hhJvhAURr2+yPHw4m6LtHa8Prunr//9/9b8YUCP88zXXfCaEMEri7WdF2HLSyQaOqGcZgAyTT2BKWxRcmyaSguL1FGUpYVKcE4ToTgeO+9LzGMT9BKUpQlX/361/jWz/0S//f/2/+Ff/qP/iHeTUhR0g09dw9bfvef/CMur664uNxweXnDctUgBLx8+RJjDcvlGjePzPNIVdWEAEpCXZUkIbFFhUgBIRXWFlhrOez3SKkASYqJ9eYaYw1VVVGWJTEGQvCklDBa0XUdAoUQoERCKsEwTEiRkGpBUVTc3Dyma3tijPR9R10v2O4eWK8umaaRN954QtPUCCGY55n9fsc0OZaLJd57pmlGKs2Tx0/YbvPLJqXEGA1CIKXgoinox4RRiod9i5GBZV1SljVNPdN3A94HvPd4N3zuif/cq15pwcXmksVyzcPDPUM/MDhFwhJToq5rUvJIKbBFgVQSKSWL1YLVZkVZVnRdxzhMTNPM0LcUVvH0yRPWmw1NU7NoGt56601+87f+U3711/8mgUCKnuAj7dDzwQ8+4Hf/yT/i0aNrLq82xBh52N4jhECQGIeBql5QFCXzNKC1Rsj8Ap56R99PvP/xPSkJqqpiGAaGcSKGSAgztqhYrtZcXl5SVRUxBpybPwuQkAopJBBQWlGWBTFG6qYEmRBS40NEa0XTNEgpAUFZljTNAh9misJycbnCFpp+aDkcDoBGKQuAtSVlVeFDpKprmqZmuVrSLFYgBAIYxw5TFCyXa2bnuFhWvPPmM54+e8I4dnR9x2JZkRCEmFitLj438J974pumxvVHfJK8+ewNfAgUZaJZlDjnKJqGsioRGJq6pqwsQki89/T9QAyRlCQ+BpQ2GFvz+v6e91YrmqbG+wA4UpJ87atfZrX8u/Rdy7d/719jrCYhOA0jP/izP+f5xx9SlhVt16GkpF43uGkkIRj6kaapKYqCrjshpcJ7QZg6PvrkY07twOVSMfR7pnFivbli9g5SwFqFtRYpJc5NCCFJCWJMSKlRUrJ4tCQEzzx7Yox471kuGpq6YnIg8YzDxGKxwHuHlIqUBOvVktPphDaavh84Hk+QQJDQRhFjwGjNoeuxxuDnkVOcKauKw+FASicWyzV+HtHaMM8jdb3ktlmglSKmwPZhi5sj1hQIIVmvLR99/Bz5l1Rvnxv4GANz1Dg3IZWkPR3OubQmBMfsZhaLJc45hITdbkdKAq0Mxlqc90gJxlqGfmSeJmoDfd+xXC4JIWCMRcmcT996603+9n/+X/HRDz9g+3BPJOJiQIrE//X//H/iv/57/y1vv/seAsH99gGFJwrDZrNmf+qpS01dL3j+8Uf88P3v8+++/Yd89P3vM7Yt/4NRWFuy3mx49s67vPHee/z0z/4cWucACJFQSuFmjxAS5/JNloC2bVksligVEELhvUcIgdYGNw9MfkYqRYiRpqmRUlLVFUpJhBDcP9whUEzzxHq9JiWd04hRJJFri5RAaY13jqouuHp0w+tXz9FGE2IEAs2i4erqkhAC+/2R7W6LURptJMY2TF5TmsDtzSM+ef76iwfe+4g2krKsczFB4mKzoapz3nbzTIyBcRhxLmC0YZo9Xk6MY09KUDc1UkjKwhDcTLO5ghSRQrBc5vwWpCDESFFWvPvul/jZn/sF/tE//AckApMfSDHxO7/zOzTLhv/iv/l7XN8+RWtDqTSqqCAlvPe8evnA8w+/xx///u/znW//Pm5yCKFICOQo6FPP7uHAi49f8u1/9a/5g3/5L/ny17/O13/6mzx96x2MsaQkUEoyjg6tDcZI9vsOIQSr1Yq+H84pIaKUZrFsKMqC43GPUvKzmyelRNseOLUtVVXj5on1+oIQPTEk+r6jLPNN0zQ1x2NHVTZMYqRrTxgjubm+5YMPfsDV1Q2zm7i+ucH7yAcfvE9MiaqscM5hbcPDbk+QFcZYNusVXT99buDF5w1p/uRP/jTFGBFwvlJblBT4GElJYE0BCJQyFIUhAQ/3rxDRkaRltVqRgsN7R1EtEVKwfdjS1BWLxZKqqRBCME0TMQamyRGC4N9++w/4P/4f/vdsd3sigrookSKxrCy/9R//Nv/l3/3fsbm4ZBp7xtGz3d7x4off43t/9Ifcv3iBHyfc7CBBAqTWkBJziJAgaEOMAmkMi6bh6vqKd7/6FX7uF/8aj26esFzWOOcJwVMUBeM4IRAslg3jOOJmjzGWkBLWKgQ5NRRFgVKKaRo5nU6M44iSBmMMiEDf9yhZgIi0pw7vZ1brNYUtGaeZeRpxfkZKRfABKcH7RNsduL6+ZRwmdvsdQoDRGkQuTqUUlGVN1x6Z3chqfUXwgd/4m7/yxar64+FACBEhoKorun7A2hpjLHVVkMhFjw+JkBLDOFKVBXM/UNZLpJI4DwiJlAKlC7quQ2sJvSYiuLhYnfPip1en45133uHJs2e8vntNSoKgJEkI5lnxP/7Tfw5K81/8b/4u7fYV3/mTP+HPvv1vONzfMfUTx3HEO4+SAq00xITSksIUaK2wxiK0RCrDFAXzNPHq1R1dO/DhD97nm9/6Fr/0q7/GxdUVKSWUkhSFJcYIkIvI+YQQ0FQWpTRCCPL5STw83DOOI0VRslqtkFLh3ExKGiklKQX6rkUmT6EFKSVOXU/X97h5pK5KYpI4YF3nDunFi8jHH3+IUhZBYLO+xEXFPA7MYaK0FUjBOM+QBPv9Hq3/vTH/ywMvVEkIgUVlubxYMw4D8zyhZGK3awGBtYaIxgfHMPRsVhu6YcSqGnSBCBI/DTy8/oTVxRPefvsdpJIkBEkoYoSqqmjblnnO12tRGn7rP/5b/OAH77PbbhmnCSElMSVSDPzB7/4O/rAn+JmHF8/pu57ZB7pxYpxdvgaNwcmAUQbpI07kl2EeBrT1KBO4WDQkaRiDIDjP9mHPH/yr3yPEyG/97b/DYtGQUsz5VynaNn9mYzSzmxAyEeNIOqeaaZrouly/KCXPf+7QOvfhUkoOhz3L1ZqyKJBSIqTk1PaU1tL1HSl5mrpgubpgnHq2ux0hRuqqQSpFjAnvZ6wp8UoxDIpSaI6HHX3fYk3FerPBu/GLB34YZ5QIkDRSKaw1aK2o6hK/d6QkmOZA252oFyuausYUFbe3T3FRoqREWk9drehVJAnFD5+/QGnF09snSOFxbsZayzhObLcPXKxXKKn4+je+xdO33ma/3+KCRyMhSi6XG66akvf/9E/wMdJPM+M0MTtPTAEpFFLKXBCd2zAhLVKAEAKlBbls98zjgFYzq2aBMgInNN4F/vgP/i1GK/7af/DruZ9WkhgTQz8hlaIoCqxR58pfQQJpDHVdU5UFx1MGbYqiJMaImz2JOd+cVQ2A8y7fKNqglcBWJVVd4dxEXVX0Q8/r13ekBEVRUFc1D9s7FosLvJ+Z3YQUAnxPXazxk6WqFhitGPojPnw+z+JzA19ana9GpQjBI6TCz579bosQgmbRkFDUdcNi0SClwBhJSApcoD3c0ZQFbgpUiwvafmCaRp5d3LJZ1RijmKaJ/W6PtZarqwsUKefL0vLrv/43+fAHf87Q9liluFkvuGgqtrsDzntCSrTjhI8RIyRKG5RUpBQZnEM4iNogK0MkMvsRayzWKESUhAApRsKxpV6CloqqrklS8N1/+8dsNhe8942fZbNZUZSaGOF4arFlSVVaYgzEmLsfgcAYg/cGJTXGaKoq1wcperSxTNOI0QatNbNzhAjOJaZxousGlBJYa9kdjtzd3bFaLmmaJf3QQUys15e0XUdZLhB4pAgsa8sw9GitWa02jOPA0B1Zr3+EPn63vePq0Q3eTWziMuczGamLJVKJz64xZQzOzXRdx6OrKxLghxatLC93E8M08+6zmkeXK64v15RVfrNPpx7nAlIpjDZUZYkbW5zzVFbz9a9/g69/46f5k2//Ic8u1qzKivv9kZQCEsHsAy6EfKVKQfARpQRaSpRWFEqjpaSbRi7Xa2KIDG4mIPAxsDA5dyujCCGhCIztAVs5jFrz3T/8PZZXV6w3S4SAotA0sWaeZpTIOTTEiCBX+FJKlNIYm5HN+Zxzc8vo0KbMuTclIDL7SNcN1IXCaIU2BbNzxJBYLtcoY0FpinoFKRL7gao2HPd3rDeXDP1IYWsQEVtWHE8Ddd0QY+Dy8kcIvAo9Mk6UdolUGbUahxnnA9MYqK2krkqm2RH8DCnlXr9uMFphyxrHyGZVs1zWGKPx3nM47Ag+IqQGYfKX5GYSFls1jLOjKCyPHl3xN/76rxAe7gjTxKEfGd2MVQIXYfCBGBNKcu40wEoFMSISoDVKWwSC19s9dbOAlCgNaK1RQpCkJimTK2TySzOeWsauI/qB7uEVhf2ZXMBJidECa/JpL4oCe66hnMvgjtYZEEop9/pCgdElwXseToHaBObhgJQ6t2H9HVYYCqOJPiGSJEZHCgM+emJRMU6BaRqJSYCy2CIfHKUMicB+t6WuV0xzZLNeslot0fpzQ/v5gV9fv4WtS9T5qrc2B0kKwaqpqasSqSRCZIizritiiiipKBcVWkue1SVSwjiMtKcTtihRyuLmnsPuNbZcUFpD3+6pFytiWSFVQUo9bu55eP4xwzhy6obz6UpMUeBjIgIxgULhY0CIyOwmrDIoIXAhImUGYrQtEDGitGL2AVNUzFIjpEQmiUcilc4zBKWJIXDaHvjDf/5PuXr8lHe+/FUQgmkYEEKwWK3PwA9Iqc6FmkLBGbbVKK3Z7ntWVYGSirrUSAJSWYQQHE8nkIKqbnDHB5ASUa7RynDstnTtC96sG0qjECERk0CaghTWdIdXXF1cslqvMLrg1B4xMrJoKoSQfPzJJ3zzm1/9gideW+5ffULZrJmGE1fXtyASiEhRGKS2CJEQJGxRYq3FWoO1FiHIRcg84b1HSk1VLwnBQUpYW1HXEUREENjfv0Jqg9YFCcE4OX73v/8H/Jt/8T+ybwdG53DeUWiFFIKYIKaE1hofA1pljLLQhsLa3MrJ8ylWmkfrOvfYPjLOjjkExDxjjQYlSSEgrUGrjM3rsjynrJH/6R/8P0m//Z9ycfuEuq7x85iBp3Ofn1JiHEeElGglSDFDskpKNnWBkAKlFOtC0B47EOADlNZg1RJrCszlDdPksEWBD4nV5hJjDVIk3DyhRKK0AlsZxnZmUTfM88zr16+QUrDZbBiGgY8/+pAEzLP74ic+BEd3PFA3G1KSGYIkX2vjOOTRqpSs1us8HBGCGCNde2KeZ7S22MJSlCXOJ3zwuMkR44zSBdoUCBFRUnD7xjtEJOM0EELg+9/9Dv/qd36H+8OROYQzbEl+oUIkQq5qAUH+M4SAEInzzLJU1EXB7eWGyiiePb7GGMu+G3n1cCDESKk1i9pSaInRColDy/y5hcyAVF0uCGPHt//xP+Tq7S/x5le+ynJzyTB5bGFw80xVN3gfECRSzL0/5O/CGAWkMxo48tHHz1mtlhRlTQozp5cf0pcVt2+9i/AwTjMxJo7tieur63NtYfFuoqobZjfj557VeolSir6fmCfPHB0CaJoFUhqG8fOnc39p4J+982WEVEAEBFVdEkJis7k4p4D5jHI5QOS5dZIUxQIh82gXPCEJSiOxTcPhBIoEKQd0njwhBIbxhDWWYRj53f/hv2e7P5GSQJy/xBgjzksKo88Bzyc/xEQkoqVCS8GqKnn39pKnt9eU1hCiYDi1dEKhq4bbqzXRTxAiIXrakyMKgZtmrDUUhaWbW4yyDGNCa0Xatrz//Y/44//pX7HcbCibBddvvMHF9TVSaea+pagqLm9usWWNUJqmbtBGfTa42u0PrFYXGA1lYYlBUSw3LC4ukVLR9SNKSsrS8OjqGlto5nkm+ImiKDC2YLs95LZU5RmKVpJgJFW1xE0D49SDkFRV9cUDf3V5RUwRYwwpRcZxRAqBMorTcUdKIJWiKmuUtmitqaqK3fYBbQxCSNq2RZ0xAB80KuWxK0lTlDnIUmmk0rTdQOs9u7tXfPj+95l9ACkQSUICFwJSCmTIEHKhNQKBEKBlhmUro/nm209YVQXt4cDrwSGNxWhNSuCHgHMT0TvqqkIiiEITU8ILQ3QgS0vQhhA8vh9JIVJVZYZ76Rm6EW0NL374AUJKxnGCqWNRl2xubnj21a/x1te+gRC36NlQ1RUheIw2SAlNZQgxoU3B1ZM3kUqx6yOyWJFczzyONE2DEBrw+Lll0VSfdQNlWbDbbnEhYrTE2oLtwx2LRck8OYyVDEP3xQO/3d0RQsyFixAoqSnKEiFEhm61IUaPtQXz7NFGU5ZVJg8gUFIxz56+P3B5eUUI+ZRqJQhuJEaTkb8Y83AnCeZp5MWHH9K2LTHlAg4EIUFKiRgjc0pIIYlKEs84xboseLxZcbtZEmfH635kcoF2mvNo1Rq0rUAaEorRzwynjsIWeTycIvoMv4phQhrDFCPjNGGVhDHnzXK2pJRomhpERhOnrqU/bDnJxPHuNXcfvM+L7/4pX/vlX+Wdb3wLpRRGa5QyeB+BiBE5RfVeIbxnWUhkaTmeHETohhnvW5xz1HWNKQrGYSR4T11btIxIXTDMnraPFNaipIHkOR17NpePvnjg62qFVIoUA0kI9scWoRPedZTFhpg8pEg/DLmVmTVlGdDa5L9ca+qqYOhOtKcD6/UKbSw+CnwUuHlASYmxltNxh5EKJzT3zz/ETxMhxc8qd8iDkBDTGQLNhIMYE5dNxTefPOLRxZJ2dBw7xxQCg3OEmMBNiJioTU0cJ4KQzOfUkZhRUuFiRMiIUobJexQwu5kYYRp76qrC+8AUAn6emIYebUtm79AxEnzAi8Q8jiRl+Pj9j+jbf8DDq9d8/a/8EjdPn1LX9flzROZ5RgpJEAHnElYlUhIsm4KULOM4En2isCV1XaO1YRx2ICJVXVGW+RYJIbKsEiHVzD5Q1iuO3QPHw/5HCHxd473DpRmBJvgBq2tKU1OUBTEkgoiMvaMqNfvjiarKuag9toSYKMqKy8sLQopYW6GNQLiIMJEYPEJqum7gcDhgrcVPgdN+i/OBFBNCSYQU5xcgvwFCCEDktqqyfPXxFavlgrt9x4tDi4sJozSj9wgpKRDcnY5cmpJls6QbJ4Q2aJ0IQuSxrTIkkVNKSAkZIoUtGMaRECM+ZNAoCUFC0k0zYpxxbqIpSmxR0B22KFHh5YRPgu39ju5f/A6vP3yfn/213+Ddn/oZlFYADENP0yyprSZqhQ8ZAgdJShKEo2oWpJgwxjCNA9M8U1cFMQRCUnjn8W6ksAWHfmJRFbRtxBQNMH/xwOdiq6SqKqTQwCUCWK0ykhVjZJ5GKgNdP+WT41zOQX6LMjYzQaTET7nXdy4wjtNnnLuu75imkcViRdceads9QoiMD4QAnIMeI4lcuEMinZks710uWZUlL3YnXuxPHIaRprA4lXAxYlWidY59P5DMCS0gREFKAaUtxuQ6QarMb1NAmEbUmX2jqoqjd0zDgFEaVRQQPMpohr5nGDp08iRjOYwz1liWFUTn8UoxTyeOxz9j7if6w5F3v/mzlIsVZVmfW8JAjJ6x21NYi6nW57ZYE0JgnBzGWHa7B2KIFIuaaRpxzjFN/gzUJNaLAhEDZZFHzV3XfvHApwjPX3zMZr1mc3GJJCG1IkSPiIJhGHj+w+9yUUtu3/sWPkmGwVPXJUVRIACEzH21zoVcVVfAiClqgpsRQqGVohtP9N0JJRL1MhMqhRAEIHzazomMpysp8TGyLgs2VcHrw4ntMHMcZ1yI+JgQCqQUCCERpqBeaFzwHPsRXVYkzkMkY4nBQ8odiCAhU0J5h3czIiVqWzAjiCGAd2hr8d4zTAPD0BOmAW0Ms4/cn44kAYvFChcLrFJsDyfEDz9kmga605H3fv6v8Oj6hjCPVM2COQia5RU+BHyIdLsdQgiMsdgzQ2ieZ2KKDMOYC1UtSUnjg+d7H77i+tE1lZXMPtD3e8Lcf/HAu3miSCMprXGzoyosMbiMr0vJPE8Zg1ZNvn7PkGWMkaZZ0HUdCEUIDqUtMeQvr64bvJvxfso1Qt/Sde25iLSsLq8ptOI0BWIMuXuQCu8zKBFjQkvJRWU59QMPg+c4zYwuMLr8BdU+D0aSMdR1A26iPewxymBDQAiJUSqDNDHmOiIFFInj6URdFERASUFT1znNKEUIMedcY2i7EyElHroBLQRCW3wyVFFRCY2OkckHInDqBtLrB8rvfofLJ09YrdYoKej6ASklEZURQCEoy4IQIofDnrLMFK6qqtisL3La8Y4kAj4okpu4WK1Ic4+uFmAlWlb0Z9zjCwVeFhtqpVA68748mrKsccOJ/WGLkIbL66ckEl0/IaRg0ZTMs8dYw7zLeHJMklIXVGWe23ddCzEXhm17ZLu9p64qFs2a/bFlnDxWa6TMFW4i5RdLiHN+hxAiIQQOQ6SdIzFl+pY1htIaZEpMs6OoFviUaLuOkCJziqgkkDFlHMC5TCfxGbyZxsyhSzHk2YKQpPZEUZQkBEoaqrIiApv1BdE5vJ/pZ0c/jNRlgTaGql7k3zcFkpD084yeNIeHBz76zp9w9eQZhRKYZoWyNd0EjYIYZuqmpus6iiJ3SNYWaGUYpwGlcufknSfFEYFhs7nAzQPOR+ZpQCmLKcrPDfzncjH7/shHn7zg1es7+r5nCEX+Z5rpRoctKlarS1wUnI5Hgo845xiHjhgj1lqcm1gtl0DicNhzf3/HPI25b/YeayRXl1es15ecuplx8phqQXnum/3/7M2NKf9/KSWSlPnv0TF5x3QOYgyR0XukloQU2e739OMIpsCFRDd0lIVBxkDwc77aSfRdS9v3BB84tke6viPOjmEYmPuWOI+o5EnesVg0XD9+xqPbpzy+fsLFcklKiWGc0GQChg8JHxJScCZjJoZ+4MUH77O7e40qCoy1BDdjVUTJACLPE/quw/ucww+7O3bb11hboFQWcIzzgC0UZdmQS93ENA5IqRj7E276Ea76P/3Od7DacHv7mKpsQPbEaSD4wGKxQWuD0obgRhbLBYvFMnMfUoZ1ldbE4Nnutjjn0FJSaAnRE30ep9ZVjVQlL1/fcbc9kcLMOHQU8jxezTQ5OE8zP6UIxpToZ0+pJc572n4mpES0BiEFzkfWRUkSgn4eM1kjeDaLJVVRZB6g1hTG4ENgnkckoJVi27Wk4CmMYXADhICigtlB8BglCWNBtb7gzXfe5fSwYLFbcNf29OOAKCrKZkkIESsFSgqiTKAycDOMjrHP7WCMiWnsqeolzsXMpTt/xlwMe07HEzFFVpsMptXNknmaOJ12Z9FFibILikrTtQdsYRnGHwGr/5mvfzUHLyaQiroytN3A5eXlmV6sKMuS5epnCDFXqH1/LnhCoGkWGZNO0NQNEGiPB2JM1E0DSPph4tS23O1Hnt/3mNTy0SevkUqjzgOgrGz5C6xeiBz43TRzIy2EQEoBHxMhhDygiAkh4DSO7I9HYnCURcE0WS5WawpbcGxbSq1RErphgOiRQp6BIhjmCS01wzQSg6epGlKMRO/xY89ifYGta7S8wRQlT/YHvvPhDzlOE0+lRGRoE11Y0jDhUsSHhDaGxXrJ0LcEWbE9TizmxNObK4zRnNoW5wJlpVHacPv0TaTM/IcUPT5EvJtZLpfMczjfoPHMBTDE4FHKf/HA101NWWaivtYSWxgujEYpeSYfJvq+ZZ5mxqHH+QhCsVgsskhBZGi17090+wPGmIxhNw2IxDQ6psmhjeHmoibNJ45HhYugmxVa3ucqm6ya+ZTNKrUgpEg3e3otqYxCTpkL7LxHpkRhNM4H+nGi63sKLUkh1xU+ONycqU/H9kgMHisk+9MRKQQeCDHgB5cLSxKnmGldhVRM00xZNUQ3I4TMZImy5Hp9wXf5kGPX4+c5n/aiwqc8yo7ThCwLVpeXrK8es1heZJ5d9CiREUEpBX17IoSRcRR0g2PZVOfABwQRqwtMU1NWJV03IJCE6OnaUxZ7rC6ZpldfPPDLZU0MESES3s3M08Ds3GeCgqo8FzzKcHP7mN1uh/cRpVQel/qJeRyYxp55dtTNCqU04zQiRR5eaFsQUqIsNPieRW1YrWpad031/GOOkydGn2lOKeYTd+YE+BDYj46nC4uRAnemUkUpISUm59gd9oTgkLZEAEpJpFA47860cWj7nhRi7gjOFDMhBClGfAxYpRHAqe+wUlAUluBngptJMfMUwiBYFIa6sEQEPiVMghjB2IJxdiSRa46LmxvqJnPilYS3n2RGb4iJFHOBZq1F2aw26seJzXpNiolpGpldpCqrTMd2ju1uS1lqtFYYu+B0PCCl+eKB79r2My2YUploUNcFSmm0NoSYJ2LD2KNUJht2XQcpMAwnOPedUhrqRYHShrY9obXN+jQpcPNIcBP7h9dcXj9lv9uz2WzYbR+Q2kJqz1Ks/DvFT0efAlyC3gU6F6mMZgqJmGJm4wLjONL1HUblNkkAs/P4GKhNneFWlb+Cfp7wIacrIXI/HVPCnF+iGCXSJtphoK4qhBQIJXNvH/Ok0UiotOI4DZltu9lkNDKEXEWniJaCZ+++R9MsSAm6zp8p2zN1kaHaEAUXq4sswPQzUZrMLipKpNZMk8f5hJt79ocjSkm6fqKqShZVyTRlltTnPZ9b1c8uIoRB6YJh9HRdnvFqbWm7Hu9yHvHOc2pb6mZBURgEkfZ4wM0OISVlVVHXC/q+I0Y4nY7MbmYYRu7v73j+/KMz7uzPsivJcrXBLNbUViPIzBvIuT0lEPIv2rrtMFMqQXHmCxiZCZDjnIUaeTQEzge6oWe337Nvj1Q2X68JgZQSHyIhJnyIWW4dQ+7fU641XIgMztPNjjkJTL1ESEl3OjJNmYFbFRm/V0pQlCVSCqZ5yjMJrXj2ztu88/Wfyuxao9lcXCJkpm8LKZjnKZNayhIpNRBQac6s4PPfE2LKs44A1mSa9mKx4PHjJwzDyDxP+Qb9nOcvmccH2vZEVdUMfQdEqmpBCH0+hVqCgOVqSYqJ4B1SCMZxoGkWhChpypz/uq5DCoE1CjBIadg+PCAQ9P3AZnOBlJpFkwcSVVlwcX2Dip5++iGTGzIjNmSipE4KqxVBityihciiUKg5Ucj8qozzjABKo7LMKiXEWUZMiATvWFVZ+57TzxmLj/GsxgUlcuvoQkQLSakVioQQim5yhHFkOh1RwSONZVkWpBDyz2nFNE5MfUdhLRebFd/6lV9FW0PXns4wsclDrZSL0WkcEWRcQap8aLzzGeMX5G7EaoZhxM1THkkrsBq69sj9/StCSKwvbr944EXylNUCRGR2HmMMMQna457VcpVHqiGSUq4sExFJRGlNN0zU9YJmsWS/30GCqq6Z54lK50lXXVcgFJdXZ8Jg06C1Zrlc4OaJerXB6LNi5JMXHNOIO8OaQUm0zKWfC4FuCujKsKgKUsz9v4+5FimtISTQQqClJp1vDyUExMCysExNrtgn50hCEGLAao1S6rMbozSaVV1xvdlQlQXRTQx9zzR2KJeHKherFeb1HSkltJb0/UxwI9JEfuaXfoOv/fwvkGJOgcv1+kzSCGdYNnPlhRKM43g2TEjYc9uXu438s0pEdFUQQ0SbAq0t93cPpJRrkGn6Eebx3k+EUFFWBY9vHyOkYnJZ1VGWJaSZ9nRkmmd8iDRnbbeKkcl5lotlJgQISdeduLAFRVHTdUeEkJRVyeQi0+xIJJxzzMNAVVZYa1hvLjgAs7Zcrha5kh9nnPeUJudtJSHIDOFOPk/QSi0+m/2rMwlSQxZYKMsYEi92O/aHHasio3xKZObOICU+BFzIs3Yl5Rk9hGF2vDqduG97mkPL07feYVEvqLVif/eKJnpUWZNSwhZFLnCnjmUh+eXf/E1+8Td+k9Vqw/39KxIBJcUZ/uaswRcsViumaSKlxDTNaK2z9g6JEJp59jg3URYlzs95+liUnI5dbpPrBS92I8Z8vmjycwN/ffuE0+HANEqUSlgrqMv8hXs/MbSnM+HRUJbFWVasKMoKM44MY5eBHKlQQrDfZ8BhtVrTtqf874ua4C9orSGGQP/qfaguuby65qOPP+F0OnB1/ZiurPDpIwQto3PMIWaARwrUud2MEXrnaYoKrbKjheBT1EfgU0TjWTZrvHccT3vmQaKExGhNVZZURuNyBssaPwT9OGbatXPcXD1idzzQ7rasbt9CWiiUoWwWOEQWnohckYiUWJWaX/xP/g4/9xu/zcXlVa5NhEQpk0fS/ZFHjy5IMTGfkUelFO5cP/V9j5QjdbVAKkFVWYxRKJVZQ0VhcoqYJ7TW6KLgVhl0/BECX1U10TvabsSHmWZxRfCOeR5xbs4t2mKDVJkYUZX12ZNGsVqtmWeHD/na6tpjBkUmR0KzaBYcjntIgdVqhfeBeZq4fe+bOO+YppknT265uX7E61f3vAR09UCdQPQjs3e4M7Gx0BKrFd2cZ9pZPJgIMWCUwp5BqJTg+tEjVFESXGCaZ/bHHaXJgxujDY2WFKoAkXt4IwVT1l/hYyaM2qLkN3/tt1hf3+Kngfe//+dMQ0e12bBerVjUNUoAfuIrP/ctfvG3/jOqekFZlmddfEFKMzF6LjYLpBAM3jM7R6EFZWkJ80gSiqqqmaaJl6+es16tsUVJ254QQlJVDXVds9ttEUiQiboqWdaGebSfG/i/BKsfsWVDP7SE4Ll7/RLnRoZhQAiN1JYQAyQoiobRQVnlPH48HpgnzzTO7HY7JucxRclmc4n3jn7oqas6EyjdxMXFBmM1ZV3RNEumaWSzvmSxWJFkyTj0SFsShKIPkSgVU0qMPiClwiqFTLkz72b/FwxcQcbKRWRR16wWa4Zx5O5w4uLyGpdytT/HhJSZv2aVpFKKWmsKrbHyXMvILOT45b/+66gnX+IH90c+fvGC64sronc0iwZ75icWRrHcLPnlv/1fU9aLcy2UyScxZDBq6DpiAO8Dzkf8PJ2nhGRuwzznXt8UbDYX+BA4HvaklCVb49gyjtn3RirBctnQtTtijLx4+eKLn3jnPILIzc0Np/0WgLbrMaZgnCba4wFT1mzWa5zLOrsUI/v9IdOKpCQKyePHN/mNBIZhZH/Y8vAwsVqv86RrGpjnbGcyzxPt6cRyuaZrO3zwiOR46+ljZu8Yppm3liumaeBwPNHNMzE6FkUGMEQITC6wsmCkymqUGCiNou07njy6oV4vePnyNZ4MJcuY2T5KSrTM93wmceQUpRY1Lw5H3nr8jL/xc7/I5p0v8cNdz3tf/Wne3Bie/7tvs39YoLVi6luSczRlwZd//hd48tbbgOQ0OTba0rUHnHdopWgPW0KILJYrSh1JImK0xXmHqUqKyjLMiY9e3fP4akVVGaK1+UWdJkIM3N/fMY0T1zdXZ/6D4v7hkP1zvmjgU5jphg4pNaUxJKHo50AMYGxJvTj31jExDAPBe8Yze+V0ym/ezeNnGQHzWQKtreHy6pa6bhFCMbsZrfJV3LV7UopUVcPxeERIzbEbefb0BilumIXk0dUjYgi8ePGciIC2Yxw65hCotMy3QMp4thCZk0eMVKbgOAx8/NEPuNlcsNDwcBxorD1zCBJlUWC1QgqDPEusSqUpvWcIkZ/66td498tf409f9VyvI0vjUbLiO9/9I548viX6iLYGJQVVs+C9n/4mIBiHnqYwSCkYp+l8EylWl9coKZmmma49cDweuQ6RsqmJAUICJSXLuiI4TxKQksTY4tz6TQgkRSk5HTtskbkHUiiOPwoDZ/vwimkOLJfLfE0lxXK1IoZEezoSvKNcXmFsQVWVjEO2DDHWsFpd0HctU7BY6Xm921KajNOf2o7DqePJ1QVNnftoqSRDrxDC0rYdXX9iuWz4+uIdxnFinifeeOMd2tORh/s7rq9viLxGCEEnBT56aqM5zSGj+iJX9Ak4jiM3q4rGKL7z4fuMY89b149ZSs22SxRlTRSSy9JSpOwAYsnFlpWChS1YrzdY5zi8/pj/8Od/CW8Mx1PL7/zD/wd+nlhXJS441quKxlqapuLR0zdQKhMsELkOUuovvvK6zpYqxlqUljTLTM6QUrLdHVg2DfM8YM4eQTEFDsc9j29v8S4iJNRVwzD0jENPP/RYrbKxVPz8efxfwrKt0YWkrGqM1dmkYByxpqBqVshiQWkttQWtBCfnUUhk9BSFoRsE09AiC4OUkmPXoXFoEherJTElpNIUEo7HHUVRA4K6EbRdy2KxoOt62nak63qsVYQIc0i89e6XEKZiaA+07ZF4eMBmSymEEPTOUxrDMM2MzvPy0LGpShgS33/xgg9ev+b26ooUIguhWNQNF+tLyhTo+47KGKKbUGGmKCuWN28gtOGhPfF7v/cv2B0O7A573NixbmpsUUA/Uj9+RlV8m/WjK8TZDMGezRdjyMxepQuMzUqdlBIpBepmkbuaKY9+LzYbhBCM00xZGE6nPVVZsV7UzFPPcX9EKJWNJGyRAbSYCa7dMBH8jzCdCylfwSEkalNm878QSeTxZ6MThYlnhK9DacM89oSosUKyXmWAYppGnt1ccTgciWGiqUtSgrKqkCJ7xlhbMo5THiuOIzc3GXkaxomiNMxziRSCzSZRVwUhBW6ubxDXj4hzz3d+/18iQ8AImIDjWZ0jpUAkwb4fWVclWkiiSIQQeXF3R2Xz3ECLrAOoCp3FlyFhRUEcA9KUFM0SVdeM40Q/jRxPR9ruhEqRprSUVqK84PG7X2Jd1zx68oT1JkuVPyWPZvAlAjNWlwzjnKd2GIbTDiUEVVHhvGQcJpTW9H1LU5WUJvfw2dXDI2SmaHkfSclTN3l+cDqd0MLQ94fPDfznVvXb3QMvnn/MNE5477h6dI3SZxu0acq5rMwsm+DzZEkoSx813RRJZNYJ5zmYtZrVeoMtK4QuqMqSacpME6ny3+OmAa0kCc1uf8KKRF0W1E3NerPh9uaGxXJJDIFnT295+603mOdsoCjIQ5VPBzKJDIxIIXN5nxKVNaTz/5SQ59l+hBgQBIwtWSyWNFWVXSyloKgaiqrEFAWFNZz2Ww4PdzBP6OhYLSrG9kASmuPLj3jv3Te5fvYmw9AxDD1d19K1Lae2zf5BdXMWcECMHpLH+Ug3TCQk8+w4HLaM48R6tc6sptnx6tUr2r5HaYM1JnsKVBVVVWbuo5bUdc2ru9e03ecjd58b+N3DayChbUaOYiRr5shCx5SyTHiapsyBi5lOtawKDt3Id3/4HFIihezoRIJ5mrBGc7lZZ1YNCYRBiERZZSmW0SbnNp0HF1IpqiqrcaVSaGN449mbNE3D69ev6NsTbT8SAKOyROVTUeWnlbrVmoDgoi4otKIwCqNldrj0Aeccp/0WCRRlTVNVLJcrlhdXNKtVJoDEAClQKkn0I24eMUpSFYZpmvGy4OMPnvP2l77Co2dvEWKGW6uqoShKirOiOINHJ2IMaK2RIsu4m/XV2RwRYshSr36WqGLJxeU1z954g6qssiJXyLM8m/Mtos5St8TtzS1l0XzxwC+WG548e5eE4uH+FS9evKAoalzw2T5USR4eHogRpBL0XZvtzaae63XFV9+8JQZ/RsZFbmOMxdqSotDMY4ebM1lRyuwA5fzM7Ea0EhgjcEmhtKUoKnwIDJPn6vIKpRT3d6/QSmFNwXR2x8jsWYlW2WmLlE+9QDD6QG0NZWEyZ17mn5EyD0U+/TOtBGWV7U6WTU1d19lmJSWMgKqpebS5YFlXXF9tsqzMlDgUcxQ8vNryb//lP2Map/OYF7RWaJ2Vs1JmHx0hMmt3GDKJUpBrACkl9WJJYTWlSWiVPmMhaw3aWKQqCNFnBxBtiDGw2+3pu6xTuLy6+uKBbxYbrFGMY8eHz+949fqeYRy5vnmMtrkV2263QGa0huAoq5ppHnHDEZUmtNFUdYM2BavViqossdbQt0dSSlRVnQ0XUjorQwPDMONcBCR1VWCM4dWrT1BKc3V1QVkV9ENLVTfYsqFuFigp6SePkQIpxF9M2uAzCLWdHKdh4qqpKa2lKQxWydyrS0mIoCV5siYSxIA2uXgyMr9McR5wpy0xONZNxZPH1/gQmYWmG2ZCjEw+8skPvkc408f9NBCDI4bwmYnC8dTizmTKTyXm0zQzDPlAZbVrQqt8u45jn38/U5Jioh9GlMp6PGMs7aljHAeEFEwxm09+8RO/WDB2J453H1MJz7Mnt2dbsplHj645HvcYY1k0K5q6Yb15RNe3GJ3pV9Vig1KfpolcZTbNAjdn5ohUBpkchclWpBebC4wtGFxgdBFEphbH6DEmt4yb9ZLtwwP6fGpCcFxcXrFZNhynmQjURuVACXn2pckfM8bIfT9QW8WqKrA6iztJWSc3ziMiBayRFBKsUnmmbvINcS7DkSSskdR1AUpztz3x+n7Hy+fPmbo+1xfC0J+OeYxaL+CcEof+mHNxlc0dh2E4t8pQ1SVFYRFSEkLEh0jf9YzjwKNHVzTn9i9Ej5LxjJ/0PDzcczwd0Nqw2lzRFPYzvsK/7/l8Bs4c2d7fcXr+Q2KSLNdrYMN6vTxLePNkqB1nPv7kOUYpnj15RFnazNBJ4EPGyI1WVFVFSpHj8UBKAudnqqIihDy6rOuK4iy5HrqOcTgxh6wde+utt9Fa8eLFx0Q/IwWsVmvGruNhf2BdFbzaHdkPjlVp8mnWitH5PNDR5kzZyiYKldWcujG3W/rTtsiipUYkSN7j555arjDWIo3NY9PgKLSkLguuLjf82QcvGOdM2Hj5+jXLQvEzX/s6X/nmz3L9+BnhDAWPYySRwZoQdtl2RWqiELnYOw94sqgErC0QQtCejrT7PcfDnvXmmvLse7teX1CVJdvtPUM/5oJ0uWH2kXAmXH/hwP/ed97nnUdLrt/+ClYpLq6fsFmvMEbz+tVzpFCURUUSgtuba4iBwpaf/eIv7vZ8/5MtX3/rFmvyBzocdpDyqFTi6foWqfK0qesOaG1Zr2qs0bipRwmoVhuUlDz/5EO88yxWl8zDiaE/8Oj2mv50QqaA1Yp2cjSFwSh5pjt9Or5VZ1BHUFlL77Pb1vVqw6PNJSrFrAlUinb/wDzlwVKSikJoElBWDWaxJp32KJ0NiD++u8ecve76aWRRLBiGkdPuNQioyopsGJFdr8uqORet+jx5O1+6IiOgzjmGvstDsWbB5uLyzMULFNacwSBJ01i6rqPvO8ap5/HjxxRFQRnzBPJ4/BEcMb7x5iNKo1iuHqOVRIjcM3700XPa04nr6xva7kBdL7hcN/Tdkb7dsb64zlCpUFxfLFgvK6q6YB6HbK4gLW6aUEqRfECgSCTqes3pdMD7E1XZsNxsmIaOlAJd19F1Jy4vbzmessPksL+n3+9YLspsBmwUpzmw60c2RUFlFaUS+ASBfOU3xiKFIhIICaTShASLssbYKp+w7R3O5QHJMDraT16RYuDx4ydcv/WljMAJgfeR2QUe2i0LrVloyTBNbI8ntrs93ie0yk4h0+wYp4FH9SZX84L/P/sYzv5+Qmbks7ENWhtSCiwWDd5Hju0JJTV1s8BJx363x7ncTrp5YvYxv9T9iK42Xzzwc3+k3NwglUUpqKrs39a2J8qqOb99Wc869B1umrBl9ll7/fIV0QfeePTkMx7e8XQkpSx71rYgeM80z1ibK9Rxzs5WKUHfHREJ6nqBczN937JaZ2GhczNKaap6zXJ1wcd//u8IMRdBpcmMGYRgWWbsvdSKFCMoTVmWHIeJ+67DOYefp8xO1YqmLOh2r+lmByGitSUSs5mRtVxcPWJxeYXUiuN+x7ZtiUpzuVpxvVpRFiVjnJnmE+Vymd02Y6KuFGWh2ayvMh0bC0QOx47NevHZRgwldR5mGfsZU3m/PzFNmUhZ1Svu7+4zPetcM2ilcUEQ50A/dExVxTS0vL4f+cWf+/IXC/zt7Rt044DCsV5fME8ju4ctwefZdRIZREhhZhpH5naLNCX7w4G6WQECKVMWCRz3nE4njClpFgvmyWX92eaClDKPXSlFSh4XoCoquvaI9A4fMhM1BEjzyDgOrJbrbB+eoFldZluQs5ZeIDBnEkWpFY8v12zefIfq6jHFYs33/vgPeflv/g1CSMZ5put6nl0sMTLilaRsNhRljUgBlRxNdNhmkU9mSlTrS0xVsfv+nzP0B6YUcfPM06dP+bt//79js1mzvLxBKYmxZWbrmuyG4X2WiwspsXX2o5vnMbdx1jDMeXS7qUraNps9GmMJPtPaN5sNp+OJaRo4nQ5cXFyyWK4IPuS5RdejVaJWP8JVrw28cXlLSp6H+1cE7zESnj55fHatyntevDPUqqAo8/UkpMimCSFQN4oYPIfDHiEUMUSmKRdViYRW6ky/iqyWC0YnECFLnJvlGoJjmifGeaTtp3NRt6Hve9rTAe8Dr198zOwDPkFlDEkKUjgrYJHEcsnjn/mr3Dx9i6qqOex3pN//N5+1V8PUc3c4sTv2XFQVq+UFi/UFqiqyooWeV6+fE/c71k8daFDG8uWf/Vme/dQ3+OjP/5TXn3yMkJFHt0946+23CUiEUgjCZzy4eXY5pwvJ/Wnkcll+BsBYm00T60KhZJ2HLn2fu4KiYJ7zUodTP1E1DUVZ0vcD/TAhZI+RZBPEMFMsG1biRwj8YlEz9Cf2+wesLXn69Bmn/R2VAcF0lhPlPJmSxp792p2LSJmo6ryn5bDfEUP2Yt0+3DEM0DRLfIjs9g8YXZ7pww68y8igqlhUBdv7VyRhECI7P93dvcosm3Hgo/f/DGUsrz/8ISFGxpBQKlGd2atGayKSeRopjKWuKopS8eZ779HUFYd+YphGCmv54w8+5KpecPnln6a4eQbKoMoSZR3D0cE003xq1+oD149vePq1ryEE/PZ/9p8zDR1d13Hz7A1MVVMbSwghO4q4mZQC1mYjhhAjF4sSSaJtW4ZhwDmDlNkarrAlr16+zCheTAgkdd2clbOJrutRUnJ9/ZgXL1/Q9232AdA1VltChML+CK5Xh+0Dx7YlJbh9fMnQtwxzwpRFNvF1E67fo7TN/8g8XYsp5x+js23H8bDHFhUxegSewi7Y7R5omiXJC6QIeDex84mpO1GWBcvliuPxnpAEx4dXCFMgk+fi4iLP9iV8+ad+lruXL3gRPFYpUgqcpmxeuKnKrGhB5LHu2LNYNkgBb7z3FZ698QavtnvcPGdHKgFldMjugBh7RFlT6gqVZqSB4uYRzfVTxHm8evvWWzx98y3S2TSpKAs2V9eZlDkMZw3ffGbpngc1Mq81SYBVghgT6/UGYwvc7CjP4Jb32TvvcDhwOh2RSmJThmO32wPzNLFossHkZrPhcDx8pgtYLNYMXUvZLL544Le7LVW9Yb1e0DQNH3/4QxKKtutJaKpqQVk0iOQIbmLutiANxlbYRY3SkuPpkIu1cWS723N1cZFdoI8tRVGzWF0iBZTVkmEakYuCsqyBiHMBpQyryxvKsmK7vaM/dnmGP8+47YSxBdLWuBhRIo9sM+kyoI1Ap0ymnLqWh/sHnjx9ymJp+Ku/9hs8//hjtqes1b/ZrHn++oHpgz/jjeM9RVFyeXFFs1yxrjXN5SOiKUjBs764Yn1zmzXqKeGdpyhLSCkrc5LIAJWUWShB1iiM4/DZWjNrC1KKOSdrgyyy43VKib7vGceewirq21uKomQae/wUmd3M5BwNGfOPwXGxWfPq1StsURIjIAS77cMXD/w0e+pGsFqvGfqz5r2scang1A1IAdNwwg8HLp+8Q1lK/Dwy9XsSiqpZ0Z4OGFsiQuJivaQsa0KYeePZM+RZGjR5D0iM0pRlQV3XvHj5CSll4uE0K2KKNIsVUmmqqkEpQ9/1nLqO0zjQzx5BJliOIRHnDNZURmMXS27efo/les3kPFobvvXXfgWZIr/z//5/cdjec10pFm8+4e544qQgiEQDmOlE8+QNYlGSkmN99Yiv/PzPs1yt8vROFxyPJ4ye0VIgKBin4exTl23Ix75lmhO2LDGm+KwiH8dMTP3056QUbLc7QkhYY7PRg80auKHdY8qG25tHjOOIdzNlWUFShOhYLld0XcfzTz7g+vqW5WL5xQNfWo1WAq01d68e8jI/IVEy0o4TpEClYdy/plve4IKnKitMuSHFmTC1hHmCwiKlYrnYUFUlL1+12JUFHMk7EgXTlGU/ddPQ96ezNajKKlkhsmeuEGzWF1lQERzf+953mOfIw3ZLP2evumyYIIgx4P0MbsQosGWVq98QqcoSrSS/8p/8Hb75C3+FD/7kj3n9wZ9DiEz9SD9mIsOyKri43FBcXLG4vGJxdcWjZ2/SrC9IKVE0NUYXFGVFf9wxDCNR5j66KGpizFLmo3NMs6esCg67BxbrbHCktWXoO7quJaUa7/V50plFpFpLtCno+gFdLpBxpm1bbFHjhoHQD7kl9XPWLfYDIJhdYByOXzzwIjm8nxiHjuPxSLO8BCm5f3hAKE1dLJnkCvP057NH3PnEuX5muVownHqSyO5NRVEglQUhuLq6xlpDd9pnFw0chVXZUJhIezrmXKrAx+zmmIWaeVWZ9HlF2Gq14flHH/Fwf4cLZ52bDxQ6URuFFhnzPhxbvJvP2yQiQqizcldQvvkuqqj5xi//KmVRcrx7xfP3v8d4OlA2S5ZXl1y/8Q7Vak1VZXuTceyYhomqrlFaY6REqUccDnsgME1Tpm2Z7AI2ze4svIzUizXewRRGIFHVDbXIxkuHQ17fFqNH6Ww1Nw490ziRQiCkhCokwZ9vCylRWlPYMiuUyoK6KjgeD3Td6YsHfrFcM88z24cHpMiTIK0thZGsVitiAhEnlCnOylOJVhZhMjZ/nAZWq1uiENnhchwJPt8g0xSyLMuWpHEgScVydcHxcMiaeW0JIXPb6yq7aI3ThBTq/CFrHt8+4V/8s39M2w/os7RZytwjR6HwQtBGwdN6wcXlI7QUdN2ALSq2+z0vt0cWVcGbj6+4uroGEovNhsXNYx7u7yhsgdSKxeYCU5QM06dfdol0nuBdDvI8Aynv0FOS9XqNkpKHh/3Zjkzm/TUhsGsnjr3nyWWNlonj/gEf8hi4aVYcj0dSimdiSSREqErDcd8jCZTNkq49Ya0mJoktMoe/KCwPw2tCSripyyPpz3k+dzp3ffsEReDu7nW23nj4hNfPf4ixNhcfpaW0ilIGSpvbl93uHqUE7fEASOZhRxiPFDqyXhTYssi3wpzbMyUF1mrqOi/+2e4ezguJChaLJXVdMbu86Ggae1L0jM6z293zvT/9Iz784AefsW2sKbC2oKoqFss1VbXC1kvCWfu2vX+V00HyFBoaK6ibms3mEikFDw937HY7Vus1l1ePEFqefXxyYOd5RirLfSeo1zdU9SKzgssS52aqqsR7nwmVKVLXZQZsEHnoIhVGRC6azCXIK8bkeQFEyzxP1HWdDY27LmP+xwPj6IgIQkp4N+Gdw/n8qVOKOD8xzx2lEbhuy7K21PZHUMsiDYv1hhd373Nz8xRb1aTw/xM0AeM0EEOiqqqzPanBGsvd6+cINKqoqaoCN0+0u9doKTIqpg3jMGT2aEyIWuLOazmUNnRdS1lWHA95sU5ZaOZpwOg8fzam5P0PfpB3uSmFOI9pP11LYmyJVfo8y3YMxwOP3ngbbTTH7SuUsawqy9tvPMZay93dy+wXby3WFjy6vuF0eMi760T++7MSJtIPM30pUWmmaWoOp566WWY7tjMl2gfHxeWG0+FI37cs9Yah7wh+omqW6M2aeeoIKC4Wa6Z54HQ6Zc3gesXp1J59hB3BTyyWa6axz6TTosAiMaZgGPP+uqzKPYE06GrNYvEj2J2RcmVfFCXLzRXDOOLdxPajP+Xpl3+BYZhIZPWqD4EYPMvlCh9m3OwJMSLVSAKMMVS1JaXANI90fW7zVosGqSTTcOIwz5xOp8+8W/PQQrKsMsKltcGWNTpGXiWf/VpTwmiNNpbSFmgp8CmgpWB2E8dxoBCR4/aex+99DWs0sb7EGMX17S2QuLt7zdCPmNjTNI+Y50BZWJrFinnOwoVpGgk+EJLjqkyUDPStz1Tss1P30LfZdWrsqOrz/tcYcd4zzzN9d+Lq0SNcEAhVZnfv0xFx2GcmzjQhz+losVjQ93ndW9f3CKkZx/nsGVjg/czxtKcqDfM4cmoHimIBMTBNHrv6Efp4ITJ/vqrqc/Gxp6kqLt76GZTJ25T6YSDFgFYLXJRUZcV+/xqQFOUCIQXeTRgtzztoNUKVLJZlvrJcZq0UhcFNE8vlOuvW1xckBNaWpOSZj3f0o0PbIu9frWqkyMYIyJRnBim7YEfyCs9u6DOX32rC3KFF9rGpK8titaIoSl6/fsUwjKgwYmRgcg6tZtp2ZL3ZZMfKaWYY87r0SCDFkRAq6vOsILkp5xqhz7t7cgYNIeQ1YWfnq+wjAMPoeLFteffJJitnZk9ZlVwVNTHC89f3XE4DVd1QVQ0xRPb7HXVdU9cbhqHLRpPTSHfaY4oGoSrKsqZ9+ITZz2fB57//+dz/GvxM1+cdsSHlwqkdBp6/3uXZsXd0/Xym+GYzAR/mPC70nhgmxv6E0opT7zkOmnH09N2J/f5ICAGkoV6sUAKij9R1Q7O8wI0DXXtgdg6jNS5EFqtLtLZoU2HLkifP3kSc59lGCtw0Ms4T+1PL7riHGKitRWrBk3e+lK1X3ITUFqUNL188Z+izR229vMSs38TW2acnhHDew1Oc/W7zZ3RupqhqxjnQ9iPzNBNCzC6fCUKETz3fYozn9SXNWdmTtflWJW43JfvdLnPxbElEoc8LIRoDd88/5LDfo5XKHDspMcYi8RQ6cTjssjuWT5RF3o2HiLQu4YU9b+r+gie+PR3yaVAlh3YgJUNdqkxqIKuP73cddQHNYslykfPcPI6oIu9SF6rIs+gxIFRJknmKVBQW5yeGwbNY1BxPI8oYitKy328pjPnMLiQmqFY3dH2LH0aMKbi6vOBv/Ppvst9t+eB73yP6wNVqxccPd1gpeXZ5kdUtwNWbb1NvHlHVS1L09F1LCI79/pBvFCLKgFZ5k0RRWJTOrhPeh8+WDU/zyPF4YL3agCo4tj0ptlw/2lBWiwzJBkcIiRCytt27TNuOAYIPtF1PXdc0dUFweeXYsRtAwCgSKXimOVCtbzG2YLe/Z7lcU5aPmPqWaRqZXEKbiiRKhARBYFFmPx4hFMYUn7o9f7ETn31dNPVyw/VmwWrZUFhDs9iw223Z3r3k6mLFarEkBYc2imkcEFJRlYusD1ttKIoaKQJXmwqpCxIGowVaSa6vr7HGMs0OqbLR8Scf/5Dj6YixBYXN7FTnJ9rTMS8LJnF5ecnXvv41/s5/9d/w9NlTju0JFzxSKRZ1TSKbHf8Hv/3b/LX/6G/Rz4mun6nqmuVyyX6XtX0xBB6227ybvg+cTkeO+y0yeeaxPw+Fsgq4LAsWiwXOOZIfMTo7gy1XK+qmxFiZN0SLTLfquhNKazivKB/Hgd3uge3Da55//4+wJnPou8OO4XTkeMhbP4wxNIuaoiwpqyYvdRpa9ocDp25i9qCUJpGt22Y3g1AYa7h98gbYFUmoL37iT4cDddVkv/kQSH5EFgVSSO7vXiGi50tf+TrD7gVy+W7O+d2JJATGKvoxsNvvaNsTzk1sLh4BEaPzL/np/vhpzHtUUkrEEHn77ffOTpaBoXfEGLC2oCxLhFBYk1+GlALP3nibv/5rv85HP/whRktuH11xd7+lHRJ/9ee+wq/91t9CmYJ+GChs5p6/ev4JCUnTlFhjqess9963jjj1PL65xJYNOkVsUdEejyzXq8/66xgdELi5uUaIbOY8DD15QJW59NmtXVLX5520OrFcLdHGEOYB5+9xsyOQ9+99cnBcrmoeVRVFmUgxU9invjvr4iaa5QqtTUY5y/L8cnV854OXPL25ZFFIWldxNwi+/uRHgGwPp5bNxS3jOFAU1WdvcGENt0+eQfTYssLXGxCSEDzjMACKec66eaksq4snyJR7UiE1h8Mx76HVkFJkv3vA+UjE0dR5uOPcmMmGbUfwDmv12acurwHtTgfG9sToEj//S3+daR4R08DtW1/hd/7ZP2GzKPmV3/i1TMzUWUJd2rx893g6sVpfsFptOB4esNZSFgWbRUAurs6TruyrD5nKbMsSpTQXFxeM44jWmmHoEWikEkBmvcaYcGepky0KqrIhhHTexNliTIEsKszN15jmmBc3ELlYNizqEq0U4zAwjh3BjYSQd/Imkfv9orCM44CbPT/4sz8BKUh6A7qkH1tCSqxsmQUsXzTw4zSf0SiTc1+9oq5Kuq5lub7KGxWDQ9cX1E1DDJ62G9hcPs7V/DQj9QJlSkopMoyYNM1yyTBMTM7x2GhiDLjZZXOlOKOSRauCrh1Q2vDwcM9qvaGumuzCUVUZJxCKxaKkKAz/4W//LY7HE7eP3+Qr3/gm1uq8z+3sxFlWeXT68oNPsjumlLTHPMEa54DtBzbLmuPpxDx7pMwumKTAsslqYWPyftngPePQM44TtrAYW2O0YBpn8g66ibouz2KJHHAhBDfX1xz2D8ToKes109xx6mbqqmShFFWtOZ16jsd7UnS4aSIkhdLZW9DaCq0VTV3zsH3g5unb1HWJsnmn3t3rkeViSVmYz1y+v1Dg+2HkcGpJQFHVJGF48cnHKG2Ro8cWNTHk0yhlXrcRY94AIYLPPbq23O/uEY2lrrNtmnNgVOL6OvfRKcyUVtEUipQxqtwHG33WwT1ht99mrzrn6bqW4/GIPDtFOJd33GltqAvN8o038c7THbeIeUbUGyDLpMZppqxrqnrJ4Xhk2VQ4F3j+/BOub58y+EilRbYlsZZh6Jh9T7O4+mwzRFVZiDNd8PS9xwbNbp5ZVAWgaBYLvJvpuiOnbuDq8hJBZJpnmsWSGANt12ZLE23P1u6Jly9fs9/dI0WiKEuWl48JLmQXkn6gPe3Qpjg7a3r60VEvGtbLJdM4sGgWQMY1PvX2/0KBXzSLvEm5KJnGiYvVktd9kRmo3RGjFWVRgL1ECEnfnrJ1d7fHSPDGYsolJnSIZD+TCjVNidIGiAx9z+wSUmdzIaU006lnaA+Zl1Y2FFby1pvPCCGx3++ZxoG2bZEqc9H2h1Oedp2lRiaKvKRXa9w8kSKsF4vzyZNnznp2zv7MrVNLrFEsmgolFdM0ZK6cLbi8vGK/37LdbvPCgE1ejLyI6TwAGqiKIptCxcTxlCv/2XmSVAiZMgd+t8dYy3rZYG0BtBgJzgVe3W/Zbu+RyWFtwXKdbU7naeLi4gL76eLm/sh6s0YpQQwzSmqOAxAERZHdsV/uOgyfb370uVW91pauPbK9f4lzjuPhiC0sbX8ikSiqJarIUp9PNWAJOBxahsnz4qHlOx+8wJQ18+z48+99n5AE/TCe99EZ7l4/59T2+CjYHwd8kNhmg6k2IEtm5+j7jtNhx277muRH/JxTQFFU9H2Pc+O58m5ANxyPLR9//BHD7Kk3j1Ayc/j2+30mipqC46nndNwxDh3OzefrX+PmmYfdjmHy+KhomiXj2NH3bYZvQ2SeHabIaUQrk5cDSCjKkrwLUZ+NnxU3F2tiCLSnQ/6ekuBhnzdxWmuZJkd72tOfjogUWa8uePbG2yyXDUoKtFHsTy2nts+yNJPpbXWzIMVAe9oTXZ83eZxfxLYfmf2PANkKIYhuom4W9NOICYJ5HLi8uCLGkD+8zh62xmicmzG2QGvBbn/EVgvevM3o1zgMvPXmG7ihY4yGulBZLqQ0tqqp6prdyzvghB2m8z47wzw7tBJUVYUtGmLIxr+kT9d2zmhdnDdmeaSEu92eZV1gbMk4jpRlRtSGYUBpjbRL5pQQOpEifPL+d9FFQfnWV85rQQv2p5GbqwwV391tGce8nEBpg3OesqwoCsvlhcSFBcdji5QmL1ZqysyKjeDnKTteKEFAUmrB4TjgBex2W07HQ+bhhcD1oxuM0ZRVleXbYUQrzTyObC4vcWPJRy+3kBIXmzXa3PHy5SsuXaKwGqkyYXNdSKRInxt4kdLn/8BPnv91Pp8P6P7k+V/t85PA/5g+Pwn8j+nzk8D/mD4/CfyP6fOTwP+YPv9fYX8yi/jKSzsAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "im_t2 = cast(tensor(1), TensorMask)\n",
    "test_eq(type(im_t2), TensorMask)\n",
    "test_eq(im_t2, tensor(1))\n",
    "ax = im_t.show(figsize=(2,2))\n",
    "_ =(im_t == im_t2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_fig_exists(ax)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Operations between `TensorMask` and `TensorImageBase` objects return the type of the `TensorImageBase` object:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = TensorMask([1,2])\n",
    "test_eq_type(TensorImage(1)+a, TensorImage([2,3]))\n",
    "test_eq_type(1-a, TensorMask([0,-1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide (last test of to_concat)\n",
    "test_eq_type(to_concat([TensorImage([1,2]), TensorImage([3,4])]), TensorImage([1,2,3,4]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorFlowField(TensorBase): pass\n",
    "TensorImage.register_func(F.grid_sample, TensorImageBase, TensorFlowField)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t1 = TensorImage([1.]).view(1,1,1,1)\n",
    "t2 = TensorFlowField([1.,1.]).view(1,1,1,2)\n",
    "test_eq_type(F.grid_sample(t1, t2), TensorImage([[[[0.25]]]]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export \n",
    "class TensorCategory(TensorBase): pass\n",
    "\n",
    "TensorBase.register_func(Tensor.__getitem__, TensorImageBase, TensorCategory)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tc = TensorCategory([1,2,3])\n",
    "mask_t = TensorMask([0,2,4,5])\n",
    "im_t = TensorImage([0,2,4,5])\n",
    "test_eq(mask_t[tc], tensor([2,4,5]))\n",
    "test_eq(im_t[tc], tensor([2,4,5]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export \n",
    "class TensorMultiCategory(TensorCategory): pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TitledTensorScalar(TensorBase):\n",
    "    \"A tensor containing a scalar that has a `show` method\"\n",
    "    def show(self, **kwargs): show_title(self.item(), **kwargs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## L -"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def tensored(self:L):\n",
    "    \"`mapped(tensor)`\"\n",
    "    return self.map(tensor)\n",
    "@patch\n",
    "def stack(self:L, dim=0):\n",
    "    \"Same as `torch.stack`\"\n",
    "    return torch.stack(list(self.tensored()), dim=dim)\n",
    "@patch\n",
    "def cat  (self:L, dim=0):\n",
    "    \"Same as `torch.cat`\"\n",
    "    return torch.cat  (list(self.tensored()), dim=dim)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h4 id=\"L.tensored\" class=\"doc_header\"><code>L.tensored</code><a href=\"__main__.py#L2\" class=\"source_link\" style=\"float:right\">[source]</a></h4>\n",
       "\n",
       "> <code>L.tensored</code>()\n",
       "\n",
       "`mapped(tensor)`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(L.tensored)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are shortcuts for `torch.stack` and `torch.cat` if your `L` contains tensors or something convertible. You can manually convert with `tensored`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = L(([1,2],[3,4]))\n",
    "test_eq(t.tensored(), [tensor(1,2),tensor(3,4)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h4 id=\"L.stack\" class=\"doc_header\"><code>L.stack</code><a href=\"__main__.py#L6\" class=\"source_link\" style=\"float:right\">[source]</a></h4>\n",
       "\n",
       "> <code>L.stack</code>(**`dim`**=*`0`*)\n",
       "\n",
       "Same as `torch.stack`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(L.stack)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(t.stack(), tensor([[1,2],[3,4]]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h4 id=\"L.cat\" class=\"doc_header\"><code>L.cat</code><a href=\"__main__.py#L10\" class=\"source_link\" style=\"float:right\">[source]</a></h4>\n",
       "\n",
       "> <code>L.cat</code>(**`dim`**=*`0`*)\n",
       "\n",
       "Same as `torch.cat`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(L.cat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(t.cat(), tensor([1,2,3,4]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Chunks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def concat(*ls):\n",
    "    \"Concatenate tensors, arrays, lists, or tuples\"\n",
    "    if not len(ls): return []\n",
    "    it = ls[0]\n",
    "    if isinstance(it,torch.Tensor): res = torch.cat(ls)\n",
    "    elif isinstance(it,ndarray): res = np.concatenate(ls)\n",
    "    else:\n",
    "        res = itertools.chain.from_iterable(map(L,ls))\n",
    "        if isinstance(it,(tuple,list)): res = type(it)(res)\n",
    "        else: res = L(res)\n",
    "    return retain_type(res, it)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a,b,c = [1],[1,2],[1,1,2]\n",
    "test_eq(concat(a,b), c)\n",
    "test_eq_type(concat(tuple (a),tuple (b)), tuple (c))\n",
    "test_eq_type(concat(array (a),array (b)), array (c))\n",
    "test_eq_type(concat(tensor(a),tensor(b)), tensor(c))\n",
    "test_eq_type(concat(TensorBase(a),TensorBase(b)), TensorBase(c))\n",
    "test_eq_type(concat([1,1],1), [1,1,1])\n",
    "test_eq_type(concat(1,1,1), L(1,1,1))\n",
    "test_eq_type(concat(L(1,2),1), L(1,2,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class Chunks:\n",
    "    \"Slice and int indexing into a list of lists\"\n",
    "    def __init__(self, chunks, lens=None):\n",
    "        self.chunks = chunks\n",
    "        self.lens = L(map(len,self.chunks) if lens is None else lens)\n",
    "        self.cumlens = np.cumsum(0+self.lens)\n",
    "        self.totlen = self.cumlens[-1]\n",
    "\n",
    "    def __getitem__(self,i):\n",
    "        if isinstance(i,slice): return retain_type(self.getslice(i), old=self.chunks[0])\n",
    "        di,idx = self.doc_idx(i)\n",
    "        return retain_type(self.chunks[di][idx], old=self.chunks[0])\n",
    "\n",
    "    def getslice(self, i):\n",
    "        st_d,st_i = self.doc_idx(ifnone(i.start,0))\n",
    "        en_d,en_i = self.doc_idx(ifnone(i.stop,self.totlen+1))\n",
    "        res = [self.chunks[st_d][st_i:(en_i if st_d==en_d else sys.maxsize)]]\n",
    "        for b in range(st_d+1,en_d): res.append(self.chunks[b])\n",
    "        if st_d!=en_d and en_d<len(self.chunks): res.append(self.chunks[en_d][:en_i])\n",
    "        return concat(*res)\n",
    "\n",
    "    def doc_idx(self, i):\n",
    "        if i<0: i=self.totlen+i # count from end\n",
    "        docidx = np.searchsorted(self.cumlens, i+1)-1\n",
    "        cl = self.cumlens[docidx]\n",
    "        return docidx,i-cl"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "docs = L(list(string.ascii_lowercase[a:b]) for a,b in ((0,3),(3,7),(7,8),(8,16),(16,24),(24,26)))\n",
    "\n",
    "b = Chunks(docs)\n",
    "test_eq([b[ o] for o in range(0,5)], ['a','b','c','d','e'])\n",
    "test_eq([b[-o] for o in range(1,6)], ['z','y','x','w','v'])\n",
    "test_eq(b[6:13], 'g,h,i,j,k,l,m'.split(','))\n",
    "test_eq(b[20:77], 'u,v,w,x,y,z'.split(','))\n",
    "test_eq(b[:5], 'a,b,c,d,e'.split(','))\n",
    "test_eq(b[:2], 'a,b'.split(','))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = torch.arange(26)\n",
    "docs = L(t[a:b] for a,b in ((0,3),(3,7),(7,8),(8,16),(16,24),(24,26)))\n",
    "b = Chunks(docs)\n",
    "test_eq([b[ o] for o in range(0,5)], range(0,5))\n",
    "test_eq([b[-o] for o in range(1,6)], [25,24,23,22,21])\n",
    "test_eq(b[6:13], torch.arange(6,13))\n",
    "test_eq(b[20:77], torch.arange(20,26))\n",
    "test_eq(b[:5], torch.arange(5))\n",
    "test_eq(b[:2], torch.arange(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "docs = L(TensorBase(t[a:b]) for a,b in ((0,3),(3,7),(7,8),(8,16),(16,24),(24,26)))\n",
    "b = Chunks(docs)\n",
    "test_eq_type(b[:2], TensorBase(range(2)))\n",
    "test_eq_type(b[:5], TensorBase(range(5)))\n",
    "test_eq_type(b[9:13], TensorBase(range(9,13)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Simple types"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def show_title(o, ax=None, ctx=None, label=None, color='black', **kwargs):\n",
    "    \"Set title of `ax` to `o`, or print `o` if `ax` is `None`\"\n",
    "    ax = ifnone(ax,ctx)\n",
    "    if ax is None: print(o)\n",
    "    elif hasattr(ax, 'set_title'):\n",
    "        t = ax.title.get_text()\n",
    "        if len(t) > 0: o = t+'\\n'+str(o)\n",
    "        ax.set_title(o, color=color)\n",
    "    elif isinstance(ax, pd.Series):\n",
    "        while label in ax: label += '_'\n",
    "        ax = ax.append(pd.Series({label: o}))\n",
    "    return ax"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_stdout(lambda: show_title(\"title\"), \"title\")\n",
    "# ensure that col names are unique when showing to a pandas series\n",
    "assert show_title(\"title\", ctx=pd.Series(dict(a=1)), label='a').equals(pd.Series(dict(a=1,a_='title')))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ShowTitle:\n",
    "    \"Base class that adds a simple `show`\"\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "class TitledInt(Int, ShowTitle):\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "class TitledFloat(Float, ShowTitle):\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "class TitledStr(Str, ShowTitle):\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "class TitledTuple(fastuple, ShowTitle):\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "add_docs(TitledInt, \"An `int` with `show`\"); add_docs(TitledStr, \"An `str` with `show`\");\n",
    "add_docs(TitledFloat, \"A `float` with `show`\"); add_docs(TitledTuple, \"A `fastuple` with `show`\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"TitledInt\" class=\"doc_header\"><code>class</code> <code>TitledInt</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>TitledInt</code>() :: [`Int`](https://fastcore.fast.ai/basics#Int)\n",
       "\n",
       "An `int` with `show`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(TitledInt, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"TitledStr\" class=\"doc_header\"><code>class</code> <code>TitledStr</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>TitledStr</code>() :: [`Str`](https://fastcore.fast.ai/basics#Str)\n",
       "\n",
       "An `str` with `show`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(TitledStr, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"TitledFloat\" class=\"doc_header\"><code>class</code> <code>TitledFloat</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>TitledFloat</code>(**`x`**=*`0`*) :: [`Float`](https://fastcore.fast.ai/basics#Float)\n",
       "\n",
       "A `float` with `show`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(TitledFloat, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_stdout(lambda: TitledStr('s').show(), 's')\n",
    "test_stdout(lambda: TitledInt(1).show(), '1')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"TitledTuple\" class=\"doc_header\"><code>class</code> <code>TitledTuple</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>TitledTuple</code>(**`x`**=*`None`*, **\\*`rest`**) :: [`fastuple`](https://fastcore.fast.ai/basics#fastuple)\n",
       "\n",
       "A [`fastuple`](https://fastcore.fast.ai/basics#fastuple) with `show`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(TitledTuple, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "df = pd.DataFrame(index = range(1))\n",
    "row = df.iloc[0]\n",
    "x = TitledFloat(2.56)\n",
    "row = x.show(ctx=row, label='lbl')\n",
    "test_eq(float(row.lbl), 2.56)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def truncate(self:TitledStr, n):\n",
    "    \"Truncate self to `n`\"\n",
    "    words = self.split(' ')[:n]\n",
    "    return TitledStr(' '.join(words))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Other functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "if not hasattr(pd.DataFrame,'_old_init'): pd.DataFrame._old_init = pd.DataFrame.__init__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def __init__(self:pd.DataFrame, data=None, index=None, columns=None, dtype=None, copy=False):\n",
    "    if data is not None and isinstance(data, Tensor): data = to_np(data)\n",
    "    self._old_init(data, index=index, columns=columns, dtype=dtype, copy=copy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def get_empty_df(n):\n",
    "    \"Return `n` empty rows of a dataframe\"\n",
    "    df = pd.DataFrame(index = range(n))\n",
    "    return [df.iloc[i] for i in range(n)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def display_df(df):\n",
    "    \"Display `df` in a notebook or defaults to print\"\n",
    "    try: from IPython.display import display, HTML\n",
    "    except: return print(df)\n",
    "    display(HTML(df.to_html()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def get_first(c):\n",
    "    \"Get the first element of c, even if c is a dataframe\"\n",
    "    return getattr(c, 'iloc', c)[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def one_param(m):\n",
    "    \"First parameter in `m`\"\n",
    "    return first(m.parameters())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def item_find(x, idx=0):\n",
    "    \"Recursively takes the `idx`-th element of `x`\"\n",
    "    if is_listy(x): return item_find(x[idx])\n",
    "    if isinstance(x,dict):\n",
    "        key = list(x.keys())[idx] if isinstance(idx, int) else idx\n",
    "        return item_find(x[key])\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def find_device(b):\n",
    "    \"Recursively search the device of `b`.\"\n",
    "    return item_find(b).device"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t2 = to_device(tensor(0))\n",
    "dev = default_device()\n",
    "test_eq(find_device(t2), dev)\n",
    "test_eq(find_device([t2,t2]), dev)\n",
    "test_eq(find_device({'a':t2,'b':t2}), dev)\n",
    "test_eq(find_device({'a':[[t2],[t2]],'b':t2}), dev)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def find_bs(b):\n",
    "    \"Recursively search the batch size of `b`.\"\n",
    "    return item_find(b).shape[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = torch.randn(4,5)\n",
    "test_eq(find_bs(x), 4)\n",
    "test_eq(find_bs([x, x]), 4)\n",
    "test_eq(find_bs({'a':x,'b':x}), 4)\n",
    "test_eq(find_bs({'a':[[x],[x]],'b':x}), 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def np_func(f):\n",
    "    \"Convert a function taking and returning numpy arrays to one taking and returning tensors\"\n",
    "    def _inner(*args, **kwargs):\n",
    "        nargs = [to_np(arg) if isinstance(arg,Tensor) else arg for arg in args]\n",
    "        return tensor(f(*nargs, **kwargs))\n",
    "    functools.update_wrapper(_inner, f)\n",
    "    return _inner"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This decorator is particularly useful for using numpy functions as fastai metrics, for instance:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import f1_score"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@np_func\n",
    "def f1(inp,targ): return f1_score(targ, inp)\n",
    "\n",
    "a1,a2 = array([0,1,1]),array([1,0,1])\n",
    "t = f1(tensor(a1),tensor(a2))\n",
    "test_eq(f1_score(a1,a2), t)\n",
    "assert isinstance(t,Tensor)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class Module(nn.Module, metaclass=PrePostInitMeta):\n",
    "    \"Same as `nn.Module`, but no need for subclasses to call `super().__init__`\"\n",
    "    def __pre_init__(self, *args, **kwargs): super().__init__()\n",
    "    def __init__(self): pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"Module\" class=\"doc_header\"><code>class</code> <code>Module</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>Module</code>() :: [`Module`](/torch_core.html#Module)\n",
       "\n",
       "Same as `nn.Module`, but no need for subclasses to call `super().__init__`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(Module, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([-0.0832], grad_fn=<AddBackward0>)"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class _T(Module):\n",
    "    def __init__(self): self.f = nn.Linear(1,1)\n",
    "    def forward(self,x): return self.f(x)\n",
    "\n",
    "t = _T()\n",
    "t(tensor([1.]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "from torch.nn.parallel import DistributedDataParallel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "def get_model(model):\n",
    "    \"Return the model maybe wrapped inside `model`.\"\n",
    "    return model.module if isinstance(model, (DistributedDataParallel, nn.DataParallel)) else model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "def one_hot(x, c):\n",
    "    \"One-hot encode `x` with `c` classes.\"\n",
    "    res = torch.zeros(c, dtype=torch.uint8)\n",
    "    if isinstance(x, Tensor) and x.numel()>0: res[x] = 1.\n",
    "    else: res[list(L(x, use_list=None))] = 1.\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(one_hot([1,4], 5), tensor(0,1,0,0,1).byte())\n",
    "test_eq(one_hot(torch.tensor([]), 5), tensor(0,0,0,0,0).byte())\n",
    "test_eq(one_hot(2, 5), tensor(0,0,1,0,0).byte())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def one_hot_decode(x, vocab=None):\n",
    "    return L(vocab[i] if vocab else i for i,x_ in enumerate(x) if x_==1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(one_hot_decode(tensor(0,1,0,0,1)), [1,4])\n",
    "test_eq(one_hot_decode(tensor(0,0,0,0,0)), [   ])\n",
    "test_eq(one_hot_decode(tensor(0,0,1,0,0)), [2  ])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def params(m):\n",
    "    \"Return all parameters of `m`\"\n",
    "    return [p for p in m.parameters()]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def trainable_params(m):\n",
    "    \"Return all trainable parameters of `m`\"\n",
    "    return [p for p in m.parameters() if p.requires_grad]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = nn.Linear(4,5)\n",
    "test_eq(trainable_params(m), [m.weight, m.bias])\n",
    "m.weight.requires_grad_(False)\n",
    "test_eq(trainable_params(m), [m.bias])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "norm_types = (nn.BatchNorm1d, nn.BatchNorm2d, nn.BatchNorm3d, nn.InstanceNorm1d, nn.InstanceNorm2d, nn.InstanceNorm3d, nn.LayerNorm)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def norm_bias_params(m, with_bias=True):\n",
    "    \"Return all bias and BatchNorm parameters\"\n",
    "    if isinstance(m, norm_types): return L(m.parameters())\n",
    "    res = L(m.children()).map(norm_bias_params, with_bias=with_bias).concat()\n",
    "    if with_bias and getattr(m, 'bias', None) is not None: res.append(m.bias)\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for norm_func in [nn.BatchNorm1d, partial(nn.InstanceNorm1d, affine=True)]:\n",
    "    model = nn.Sequential(nn.Linear(10,20), norm_func(20), nn.Conv1d(3,4, 3))\n",
    "    test_eq(norm_bias_params(model), [model[0].bias, model[1].weight, model[1].bias, model[2].bias])\n",
    "    model = nn.ModuleList([nn.Linear(10,20, bias=False), nn.Sequential(norm_func(20), nn.Conv1d(3,4,3))])\n",
    "    test_eq(norm_bias_params(model), [model[1][0].weight, model[1][0].bias, model[1][1].bias])\n",
    "    model = nn.ModuleList([nn.Linear(10,20), nn.Sequential(norm_func(20), nn.Conv1d(3,4,3))])\n",
    "    test_eq(norm_bias_params(model, with_bias=False), [model[1][0].weight, model[1][0].bias])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def batch_to_samples(b, max_n=10):\n",
    "    \"'Transposes' a batch to (at most `max_n`) samples\"\n",
    "    if isinstance(b, Tensor): return retain_types(list(b[:max_n]), [b])\n",
    "    else:\n",
    "        res = L(b).map(partial(batch_to_samples,max_n=max_n))\n",
    "        return retain_types(res.zip(), [b])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([1,2,3])\n",
    "test_eq(batch_to_samples([t,t+1], max_n=2), ([1,2],[2,3]))\n",
    "test_eq(batch_to_samples(tensor([1,2,3]), 10), [1, 2, 3])\n",
    "test_eq(batch_to_samples([tensor([1,2,3]), tensor([4,5,6])], 10), [(1, 4), (2, 5), (3, 6)])\n",
    "test_eq(batch_to_samples([tensor([1,2,3]), tensor([4,5,6])], 2), [(1, 4), (2, 5)])\n",
    "test_eq(batch_to_samples([tensor([1,2,3]), [tensor([4,5,6]),tensor([7,8,9])]], 10), \n",
    "        [(1, (4, 7)), (2, (5, 8)), (3, (6, 9))])\n",
    "test_eq(batch_to_samples([tensor([1,2,3]), [tensor([4,5,6]),tensor([7,8,9])]], 2), [(1, (4, 7)), (2, (5, 8))])\n",
    "\n",
    "t = fastuple(tensor([1,2,3]),TensorBase([2,3,4]))\n",
    "test_eq_type(batch_to_samples(t)[0][1], TensorBase(2))\n",
    "test_eq(batch_to_samples(t).map(type), [fastuple]*3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def interp_1d(x:Tensor, xp, fp):\n",
    "    \"Same as `np.interp`\"\n",
    "    slopes = (fp[1:]-fp[:-1])/(xp[1:]-xp[:-1])\n",
    "    incx = fp[:-1] - (slopes*xp[:-1])\n",
    "    locs = (x[:,None]>=xp[None,:]).long().sum(1)-1\n",
    "    locs = locs.clamp(0,len(slopes)-1)\n",
    "    return slopes[locs]*x + incx[locs]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "brks = tensor(0,1,2,4,8,64).float()\n",
    "ys = tensor(range_of(brks)).float()\n",
    "ys /= ys[-1].item()\n",
    "pts = tensor(0.2,0.5,0.8,3,5,63)\n",
    "\n",
    "preds = pts.interp_1d(brks, ys)\n",
    "test_close(preds.numpy(), np.interp(pts.numpy(), brks.numpy(), ys.numpy()))\n",
    "\n",
    "plt.scatter(brks,ys)\n",
    "plt.scatter(pts,preds)\n",
    "plt.legend(['breaks','preds']);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def pca(x:Tensor, k=2):\n",
    "    \"Compute PCA of `x` with `k` dimensions.\"\n",
    "    x = x-torch.mean(x,0)\n",
    "    U,S,V = torch.svd(x.t())\n",
    "    return torch.mm(x,U[:,:k])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "def logit(x):\n",
    "    \"Logit of `x`, clamped to avoid inf.\"\n",
    "    x = x.clamp(1e-7, 1-1e-7)\n",
    "    return -(1/x-1).log()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def num_distrib():\n",
    "    \"Return the number of processes in distributed training (if applicable).\"\n",
    "    return int(os.environ.get('WORLD_SIZE', 0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def rank_distrib():\n",
    "    \"Return the distributed rank of this process (if applicable).\"\n",
    "    return int(os.environ.get('RANK', 0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def distrib_barrier():\n",
    "    \"Place a synchronization barrier in distributed training\"\n",
    "    if num_distrib() > 1 and torch.distributed.is_initialized(): torch.distributed.barrier()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After calling this, ALL sub-processes in the pytorch process group must arrive here before proceeding."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "# Saving arrays requires pytables - optional dependency\n",
    "try: import tables\n",
    "except: pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _comp_filter(lib='lz4',lvl=3): return tables.Filters(complib=f'blosc:{lib}', complevel=lvl)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def save_array(p:Path, o, complib='lz4', lvl=3):\n",
    "    \"Save numpy array to a compressed `pytables` file, using compression level `lvl`\"\n",
    "    if isinstance(o,Tensor): o = to_np(o)\n",
    "    with tables.open_file(p, mode='w', filters=_comp_filter(lib=complib,lvl=lvl)) as f: f.create_carray('/', 'data', obj=o)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Compression lib can be any of: blosclz, lz4, lz4hc, snappy, zlib or zstd."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def load_array(p:Path):\n",
    "    \"Save numpy array to a `pytables` file\"\n",
    "    with tables.open_file(p, 'r') as f: return f.root.data.read()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def base_doc(elt):\n",
    "    \"Print a base documentation of `elt`\"\n",
    "    name = getattr(elt, '__qualname__', getattr(elt, '__name__', ''))\n",
    "    print(f'{name}{inspect.signature(elt)}\\n{inspect.getdoc(elt)}\\n')\n",
    "    print('To get a prettier result with hyperlinks to source code and documentation, install nbdev: pip install nbdev')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def doc(elt):\n",
    "    \"Try to use doc form nbdev and fall back to `base_doc`\"\n",
    "    try:\n",
    "        from nbdev.showdoc import doc\n",
    "        doc(elt)\n",
    "    except: base_doc(elt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def nested_reorder(t, idxs):\n",
    "    \"Reorder all tensors in `t` using `idxs`\"\n",
    "    if isinstance(t, (Tensor,L)): return t[idxs]\n",
    "    elif is_listy(t): return type(t)(nested_reorder(t_, idxs) for t_ in t)\n",
    "    if t is None: return t\n",
    "    raise TypeError(f\"Expected tensor, tuple, list or L but got {type(t)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = tensor([0,1,2,3,4,5])\n",
    "idxs = tensor([2,5,1,0,3,4])\n",
    "test_eq_type(nested_reorder(([x], x), idxs), ([idxs], idxs))\n",
    "\n",
    "y = L(0,1,2,3,4,5)\n",
    "z = L(i.item() for i in idxs)\n",
    "test_eq_type(nested_reorder((y, x), idxs), (z,idxs))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Image helpers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def make_cross_image(bw=True):\n",
    "    \"Create a tensor containing a cross image, either `bw` (True) or color\"\n",
    "    if bw:\n",
    "        im = torch.zeros(5,5)\n",
    "        im[2,:] = 1.\n",
    "        im[:,2] = 1.\n",
    "    else:\n",
    "        im = torch.zeros(3,5,5)\n",
    "        im[0,2,:] = 1.\n",
    "        im[1,:,2] = 1.\n",
    "    return im"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(make_cross_image(), cmap=\"Greys\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(make_cross_image(False).permute(1,2,0));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def show_image_batch(b, show=show_titled_image, items=9, cols=3, figsize=None, **kwargs):\n",
    "    \"Display batch `b` in a grid of size `items` with `cols` width\"\n",
    "    if items<cols: cols=items\n",
    "    rows = (items+cols-1) // cols\n",
    "    if figsize is None: figsize = (cols*3, rows*3)\n",
    "    fig,axs = plt.subplots(rows, cols, figsize=figsize)\n",
    "    for *o,ax in zip(*to_cpu(b), axs.flatten()): show(o, ax=ax, **kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x216 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_image_batch(([Image.open(TEST_IMAGE_BW),Image.open(TEST_IMAGE)],['bw','color']), items=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Model init"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def requires_grad(m):\n",
    "    \"Check if the first parameter of `m` requires grad or not\"\n",
    "    ps = list(m.parameters())\n",
    "    return ps[0].requires_grad if len(ps)>0 else False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Linear(4,5)\n",
    "assert requires_grad(tst)\n",
    "for p in tst.parameters(): p.requires_grad_(False)\n",
    "assert not requires_grad(tst)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def init_default(m, func=nn.init.kaiming_normal_):\n",
    "    \"Initialize `m` weights with `func` and set `bias` to 0.\"\n",
    "    if func:\n",
    "        if hasattr(m, 'weight'): func(m.weight)\n",
    "        if hasattr(m, 'bias') and hasattr(m.bias, 'data'): m.bias.data.fill_(0.)\n",
    "    return m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Linear(4,5)\n",
    "tst.weight.data.uniform_(-1,1)\n",
    "tst.bias.data.uniform_(-1,1)\n",
    "tst = init_default(tst, func = lambda x: x.data.fill_(1.))\n",
    "test_eq(tst.weight, torch.ones(5,4))\n",
    "test_eq(tst.bias, torch.zeros(5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def cond_init(m, func):\n",
    "    \"Apply `init_default` to `m` unless it's a batchnorm module\"\n",
    "    if (not isinstance(m, norm_types)) and requires_grad(m): init_default(m, func)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Linear(4,5)\n",
    "tst.weight.data.uniform_(-1,1)\n",
    "tst.bias.data.uniform_(-1,1)\n",
    "cond_init(tst, func = lambda x: x.data.fill_(1.))\n",
    "test_eq(tst.weight, torch.ones(5,4))\n",
    "test_eq(tst.bias, torch.zeros(5))\n",
    "\n",
    "tst = nn.BatchNorm2d(5)\n",
    "init = [tst.weight.clone(), tst.bias.clone()]\n",
    "cond_init(tst, func = lambda x: x.data.fill_(1.))\n",
    "test_eq(tst.weight, init[0])\n",
    "test_eq(tst.bias, init[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def apply_leaf(m, f):\n",
    "    \"Apply `f` to children of `m`.\"\n",
    "    c = m.children()\n",
    "    if isinstance(m, nn.Module): f(m)\n",
    "    for l in c: apply_leaf(l,f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Sequential(nn.Linear(4,5), nn.Sequential(nn.Linear(4,5), nn.Linear(4,5)))\n",
    "apply_leaf(tst, partial(init_default, func=lambda x: x.data.fill_(1.)))\n",
    "for l in [tst[0], *tst[1]]: test_eq(l.weight, torch.ones(5,4))\n",
    "for l in [tst[0], *tst[1]]: test_eq(l.bias,   torch.zeros(5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def apply_init(m, func=nn.init.kaiming_normal_):\n",
    "    \"Initialize all non-batchnorm layers of `m` with `func`.\"\n",
    "    apply_leaf(m, partial(cond_init, func=func))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Sequential(nn.Linear(4,5), nn.Sequential(nn.Linear(4,5), nn.BatchNorm1d(5)))\n",
    "init = [tst[1][1].weight.clone(), tst[1][1].bias.clone()]\n",
    "apply_init(tst, func=lambda x: x.data.fill_(1.))\n",
    "for l in [tst[0], tst[1][0]]: test_eq(l.weight, torch.ones(5,4))\n",
    "for l in [tst[0], tst[1][0]]: test_eq(l.bias,   torch.zeros(5))\n",
    "test_eq(tst[1][1].weight, init[0])\n",
    "test_eq(tst[1][1].bias,   init[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## autograd jit functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def script_use_ctx(f):\n",
    "    \"Decorator: create jit script and pass everything in `ctx.saved_variables to `f`, after `*args`\"\n",
    "    sf = torch.jit.script(f)\n",
    "    def _f(ctx, *args, **kwargs): return sf(*args, *ctx.saved_variables, **kwargs)\n",
    "    return update_wrapper(_f,f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def script_save_ctx(static, *argidx):\n",
    "    \"Decorator: create jit script and save args with indices `argidx` using `ctx.save_for_backward`\"\n",
    "    def _dec(f):\n",
    "        sf = torch.jit.script(f)\n",
    "        def _f(ctx, *args, **kwargs):\n",
    "            if argidx:\n",
    "                save = [args[o] for o in argidx]\n",
    "                ctx.save_for_backward(*save)\n",
    "            if not argidx: args = [ctx]+args\n",
    "            return sf(*args, **kwargs)\n",
    "        if static: _f = staticmethod(_f)\n",
    "        return update_wrapper(_f,f)\n",
    "    return _dec"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def script_fwd(*argidx):\n",
    "    \"Decorator: create static jit script and save args with indices `argidx` using `ctx.save_for_backward`\"\n",
    "    return script_save_ctx(True, *argidx)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def script_bwd(f):\n",
    "    \"Decorator: create static jit script and pass everything in `ctx.saved_variables to `f`, after `*args`\"\n",
    "    return staticmethod(script_use_ctx(f))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def grad_module(cls):\n",
    "    \"Decorator: convert `cls` into an autograd function\"\n",
    "    class _c(nn.Module):\n",
    "        def forward(self, *args, **kwargs): return cls.apply(*args, **kwargs)\n",
    "    return _c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Export -"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Converted 00_torch_core.ipynb.\n",
      "Converted 01_layers.ipynb.\n",
      "Converted 01a_losses.ipynb.\n",
      "Converted 02_data.load.ipynb.\n",
      "Converted 03_data.core.ipynb.\n",
      "Converted 04_data.external.ipynb.\n",
      "Converted 05_data.transforms.ipynb.\n",
      "Converted 06_data.block.ipynb.\n",
      "Converted 07_vision.core.ipynb.\n",
      "Converted 08_vision.data.ipynb.\n",
      "Converted 09_vision.augment.ipynb.\n",
      "Converted 09b_vision.utils.ipynb.\n",
      "Converted 09c_vision.widgets.ipynb.\n",
      "Converted 10_tutorial.pets.ipynb.\n",
      "Converted 10b_tutorial.albumentations.ipynb.\n",
      "Converted 11_vision.models.xresnet.ipynb.\n",
      "Converted 12_optimizer.ipynb.\n",
      "Converted 13_callback.core.ipynb.\n",
      "Converted 13a_learner.ipynb.\n",
      "Converted 13b_metrics.ipynb.\n",
      "Converted 14_callback.schedule.ipynb.\n",
      "Converted 14a_callback.data.ipynb.\n",
      "Converted 15_callback.hook.ipynb.\n",
      "Converted 15a_vision.models.unet.ipynb.\n",
      "Converted 16_callback.progress.ipynb.\n",
      "Converted 17_callback.tracker.ipynb.\n",
      "Converted 18_callback.fp16.ipynb.\n",
      "Converted 18a_callback.training.ipynb.\n",
      "Converted 18b_callback.preds.ipynb.\n",
      "Converted 19_callback.mixup.ipynb.\n",
      "Converted 20_interpret.ipynb.\n",
      "Converted 20a_distributed.ipynb.\n",
      "Converted 21_vision.learner.ipynb.\n",
      "Converted 22_tutorial.imagenette.ipynb.\n",
      "Converted 23_tutorial.vision.ipynb.\n",
      "Converted 24_tutorial.image_sequence.ipynb.\n",
      "Converted 24_tutorial.siamese.ipynb.\n",
      "Converted 24_vision.gan.ipynb.\n",
      "Converted 30_text.core.ipynb.\n",
      "Converted 31_text.data.ipynb.\n",
      "Converted 32_text.models.awdlstm.ipynb.\n",
      "Converted 33_text.models.core.ipynb.\n",
      "Converted 34_callback.rnn.ipynb.\n",
      "Converted 35_tutorial.wikitext.ipynb.\n",
      "Converted 37_text.learner.ipynb.\n",
      "Converted 38_tutorial.text.ipynb.\n",
      "Converted 39_tutorial.transformers.ipynb.\n",
      "Converted 40_tabular.core.ipynb.\n",
      "Converted 41_tabular.data.ipynb.\n",
      "Converted 42_tabular.model.ipynb.\n",
      "Converted 43_tabular.learner.ipynb.\n",
      "Converted 44_tutorial.tabular.ipynb.\n",
      "Converted 45_collab.ipynb.\n",
      "Converted 46_tutorial.collab.ipynb.\n",
      "Converted 50_tutorial.datablock.ipynb.\n",
      "Converted 60_medical.imaging.ipynb.\n",
      "Converted 61_tutorial.medical_imaging.ipynb.\n",
      "Converted 65_medical.text.ipynb.\n",
      "Converted 70_callback.wandb.ipynb.\n",
      "Converted 71_callback.tensorboard.ipynb.\n",
      "Converted 72_callback.neptune.ipynb.\n",
      "Converted 73_callback.captum.ipynb.\n",
      "Converted 74_callback.azureml.ipynb.\n",
      "Converted 97_test_utils.ipynb.\n",
      "Converted 99_pytorch_doc.ipynb.\n",
      "Converted dev-setup.ipynb.\n",
      "Converted index.ipynb.\n",
      "Converted quick_start.ipynb.\n",
      "Converted tutorial.ipynb.\n"
     ]
    }
   ],
   "source": [
    "#hide\n",
    "from nbdev.export import notebook2script\n",
    "notebook2script()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "jupytext": {
   "split_at_heading": true
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
